diff --git a/testing/xpcshell/xpcshell.ini b/testing/xpcshell/xpcshell.ini index c6feca39099e..68fe6d89160a 100644 --- a/testing/xpcshell/xpcshell.ini +++ b/testing/xpcshell/xpcshell.ini @@ -24,6 +24,7 @@ skip-if = os == "android" [include:toolkit/components/places/tests/autocomplete/xpcshell.ini] [include:toolkit/components/places/tests/inline/xpcshell.ini] [include:toolkit/components/places/tests/expiration/xpcshell.ini] +[include:toolkit/components/places/tests/favicons/xpcshell.ini] [include:toolkit/components/places/tests/sync/xpcshell.ini] [include:toolkit/components/places/tests/bookmarks/xpcshell.ini] [include:toolkit/components/places/tests/queries/xpcshell.ini] diff --git a/toolkit/components/places/tests/Makefile.in b/toolkit/components/places/tests/Makefile.in index bd99b6aa4438..3efab8acc6da 100644 --- a/toolkit/components/places/tests/Makefile.in +++ b/toolkit/components/places/tests/Makefile.in @@ -50,6 +50,7 @@ XPCSHELL_TESTS = \ autocomplete \ bookmarks \ expiration \ + favicons \ inline \ migration \ network \ diff --git a/toolkit/components/places/tests/bookmarks/test_async_observers.js b/toolkit/components/places/tests/bookmarks/test_async_observers.js index c12617b53327..c1b23b41beb6 100644 --- a/toolkit/components/places/tests/bookmarks/test_async_observers.js +++ b/toolkit/components/places/tests/bookmarks/test_async_observers.js @@ -5,7 +5,6 @@ * events like visit or favicon additions. */ const NOW = Date.now() * 1000; -const ICON_URI = NetUtil.newURI(do_get_file("../unit/favicon-normal32.png")); let observer = { bookmarks: [], @@ -28,7 +27,7 @@ let observer = { do_check_neq(this.bookmarks.indexOf(aItemId), -1); if (aProperty == "favicon") { do_check_false(aIsAnnotation); - do_check_eq(aNewValue, ICON_URI.spec); + do_check_eq(aNewValue, SMALLPNG_DATA_URI.spec); do_check_eq(aLastModified, 0); do_check_eq(aItemType, PlacesUtils.bookmarks.TYPE_BOOKMARK); } @@ -75,8 +74,8 @@ let gTests = [ function add_icon_test() { observer.reset(); - PlacesUtils.favicons.setAndLoadFaviconForPage(NetUtil.newURI("http://book.ma.rk/"), - ICON_URI, true); + PlacesUtils.favicons.setAndFetchFaviconForPage(NetUtil.newURI("http://book.ma.rk/"), + SMALLPNG_DATA_URI, true); }, function remove_page_test() { diff --git a/toolkit/components/places/tests/chrome/test_favicon_annotations.xul b/toolkit/components/places/tests/chrome/test_favicon_annotations.xul index 3eb9eec2b082..8db5686bd0d0 100644 --- a/toolkit/components/places/tests/chrome/test_favicon_annotations.xul +++ b/toolkit/components/places/tests/chrome/test_favicon_annotations.xul @@ -148,9 +148,15 @@ function test() return ios.newURI(aSpec, null, null); }; - // Favicon data to store - fs.setFaviconDataFromDataURL(uri(testURIs[1]), expectedURIs[1], - (Date.now() + 60 * 60 * 24 * 1000) * 1000); + // Set the favicon data. Note that the "moz-anno:" protocol requires the + // favicon to be stored in the database, but the replaceFaviconDataFromDataURL + // function will not save the favicon unless it is associated with a page. + // Thus, we must associate the icon with a page explicitly in order for it to + // be visible through the protocol. + fs.replaceFaviconDataFromDataURL(uri(testURIs[1]), expectedURIs[1], + (Date.now() + 60 * 60 * 24 * 1000) * 1000); + fs.setAndFetchFaviconForPage(uri("http://example.com/favicon_annotations"), + uri(testURIs[1]), true); // And start our test process. loadNextTest(); diff --git a/toolkit/components/places/tests/unit/expected-favicon-big16.ico.png b/toolkit/components/places/tests/favicons/expected-favicon-big16.ico.png similarity index 100% rename from toolkit/components/places/tests/unit/expected-favicon-big16.ico.png rename to toolkit/components/places/tests/favicons/expected-favicon-big16.ico.png diff --git a/toolkit/components/places/tests/unit/expected-favicon-big32.jpg.png b/toolkit/components/places/tests/favicons/expected-favicon-big32.jpg.png similarity index 100% rename from toolkit/components/places/tests/unit/expected-favicon-big32.jpg.png rename to toolkit/components/places/tests/favicons/expected-favicon-big32.jpg.png diff --git a/toolkit/components/places/tests/unit/expected-favicon-big4.jpg.png b/toolkit/components/places/tests/favicons/expected-favicon-big4.jpg.png similarity index 100% rename from toolkit/components/places/tests/unit/expected-favicon-big4.jpg.png rename to toolkit/components/places/tests/favicons/expected-favicon-big4.jpg.png diff --git a/toolkit/components/places/tests/unit/expected-favicon-big48.ico.png b/toolkit/components/places/tests/favicons/expected-favicon-big48.ico.png similarity index 100% rename from toolkit/components/places/tests/unit/expected-favicon-big48.ico.png rename to toolkit/components/places/tests/favicons/expected-favicon-big48.ico.png diff --git a/toolkit/components/places/tests/unit/expected-favicon-big64.png.png b/toolkit/components/places/tests/favicons/expected-favicon-big64.png.png similarity index 100% rename from toolkit/components/places/tests/unit/expected-favicon-big64.png.png rename to toolkit/components/places/tests/favicons/expected-favicon-big64.png.png diff --git a/toolkit/components/places/tests/unit/expected-favicon-scale160x3.jpg.png b/toolkit/components/places/tests/favicons/expected-favicon-scale160x3.jpg.png similarity index 100% rename from toolkit/components/places/tests/unit/expected-favicon-scale160x3.jpg.png rename to toolkit/components/places/tests/favicons/expected-favicon-scale160x3.jpg.png diff --git a/toolkit/components/places/tests/unit/expected-favicon-scale3x160.jpg.png b/toolkit/components/places/tests/favicons/expected-favicon-scale3x160.jpg.png similarity index 100% rename from toolkit/components/places/tests/unit/expected-favicon-scale3x160.jpg.png rename to toolkit/components/places/tests/favicons/expected-favicon-scale3x160.jpg.png diff --git a/toolkit/components/places/tests/unit/favicon-big16.ico b/toolkit/components/places/tests/favicons/favicon-big16.ico similarity index 100% rename from toolkit/components/places/tests/unit/favicon-big16.ico rename to toolkit/components/places/tests/favicons/favicon-big16.ico diff --git a/toolkit/components/places/tests/unit/favicon-big32.jpg b/toolkit/components/places/tests/favicons/favicon-big32.jpg similarity index 100% rename from toolkit/components/places/tests/unit/favicon-big32.jpg rename to toolkit/components/places/tests/favicons/favicon-big32.jpg diff --git a/toolkit/components/places/tests/unit/favicon-big4.jpg b/toolkit/components/places/tests/favicons/favicon-big4.jpg similarity index 100% rename from toolkit/components/places/tests/unit/favicon-big4.jpg rename to toolkit/components/places/tests/favicons/favicon-big4.jpg diff --git a/toolkit/components/places/tests/unit/favicon-big48.ico b/toolkit/components/places/tests/favicons/favicon-big48.ico similarity index 100% rename from toolkit/components/places/tests/unit/favicon-big48.ico rename to toolkit/components/places/tests/favicons/favicon-big48.ico diff --git a/toolkit/components/places/tests/unit/favicon-big64.png b/toolkit/components/places/tests/favicons/favicon-big64.png similarity index 100% rename from toolkit/components/places/tests/unit/favicon-big64.png rename to toolkit/components/places/tests/favicons/favicon-big64.png diff --git a/toolkit/components/places/tests/unit/favicon-normal16.png b/toolkit/components/places/tests/favicons/favicon-normal16.png similarity index 100% rename from toolkit/components/places/tests/unit/favicon-normal16.png rename to toolkit/components/places/tests/favicons/favicon-normal16.png diff --git a/toolkit/components/places/tests/unit/favicon-normal32.png b/toolkit/components/places/tests/favicons/favicon-normal32.png similarity index 100% rename from toolkit/components/places/tests/unit/favicon-normal32.png rename to toolkit/components/places/tests/favicons/favicon-normal32.png diff --git a/toolkit/components/places/tests/unit/favicon-scale160x3.jpg b/toolkit/components/places/tests/favicons/favicon-scale160x3.jpg similarity index 100% rename from toolkit/components/places/tests/unit/favicon-scale160x3.jpg rename to toolkit/components/places/tests/favicons/favicon-scale160x3.jpg diff --git a/toolkit/components/places/tests/unit/favicon-scale3x160.jpg b/toolkit/components/places/tests/favicons/favicon-scale3x160.jpg similarity index 100% rename from toolkit/components/places/tests/unit/favicon-scale3x160.jpg rename to toolkit/components/places/tests/favicons/favicon-scale3x160.jpg diff --git a/toolkit/components/places/tests/favicons/head_favicons.js b/toolkit/components/places/tests/favicons/head_favicons.js new file mode 100644 index 000000000000..04f83419df78 --- /dev/null +++ b/toolkit/components/places/tests/favicons/head_favicons.js @@ -0,0 +1,140 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Places Unit Tests. + * + * The Initial Developer of the Original Code is the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Marco Bonardo + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +const Ci = Components.interfaces; +const Cc = Components.classes; +const Cr = Components.results; +const Cu = Components.utils; + +Cu.import("resource://gre/modules/Services.jsm"); + +// Import common head. +let (commonFile = do_get_file("../head_common.js", false)) { + let uri = Services.io.newFileURI(commonFile); + Services.scriptloader.loadSubScript(uri.spec, this); +} + +// Put any other stuff relative to this test folder below. + + +// This error icon must stay in sync with FAVICON_ERRORPAGE_URL in +// nsIFaviconService.idl, aboutCertError.xhtml and netError.xhtml. +const FAVICON_ERRORPAGE_URI = + NetUtil.newURI("chrome://global/skin/icons/warning-16.png"); + +/** + * Waits for the first OnPageChanged notification for ATTRIBUTE_FAVICON, and + * verifies that it matches the expected page URI and associated favicon URI. + * + * This function also double-checks the GUID parameter of the notification. + * + * @param aExpectedPageURI + * nsIURI object of the page whose favicon should change. + * @param aExpectedFaviconURI + * nsIURI object of the newly associated favicon. + * @param aCallback + * This function is called after the check finished. + */ +function waitForFaviconChanged(aExpectedPageURI, aExpectedFaviconURI, + aCallback) { + let historyObserver = { + __proto__: NavHistoryObserver.prototype, + onPageChanged: function WFFC_onPageChanged(aURI, aWhat, aValue, aGUID) { + if (aWhat != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) { + return; + } + PlacesUtils.history.removeObserver(this); + + do_check_true(aURI.equals(aExpectedPageURI)); + do_check_eq(aValue, aExpectedFaviconURI.spec); + do_check_guid_for_uri(aURI, aGUID); + aCallback(); + } + }; + PlacesUtils.history.addObserver(historyObserver, false); +} + +/** + * Checks that the favicon for the given page matches the provided data. + * + * @param aPageURI + * nsIURI object for the page to check. + * @param aExpectedMimeType + * Expected MIME type of the icon, for example "image/png". + * @param aExpectedData + * Expected icon data, expressed as an array of byte values. + * @param aCallback + * This function is called after the check finished. + */ +function checkFaviconDataForPage(aPageURI, aExpectedMimeType, aExpectedData, + aCallback) { + PlacesUtils.favicons.getFaviconDataForPage(aPageURI, + function CFDFP_onFaviconDataAvailable(aURI, aDataLen, aData, aMimeType) { + do_check_eq(aExpectedMimeType, aMimeType); + do_check_true(compareArrays(aExpectedData, aData)); + do_check_guid_for_uri(aPageURI); + aCallback(); + }); +} + +/** + * Checks that the given page has no associated favicon. + * + * @param aPageURI + * nsIURI object for the page to check. + * @param aCallback + * This function is called after the check finished. + */ +function checkFaviconMissingForPage(aPageURI, aCallback) { + // Ask for the favicon associated with the page, expecting not to be notified. + let notificationReceived = false; + PlacesUtils.favicons.getFaviconURLForPage(aPageURI, + function CFMFP_onFaviconDataAvailable() { + notificationReceived = true; + }); + + // We must wait for the asynchronous database thread to finish the operation, + // and then for the main thread to process any pending notifications that came + // from the asynchronous thread, before we can be sure that + // onFaviconDataAvailable was not invoked in the meantime. + waitForAsyncUpdates(function CFMFP_asyncUpdates() { + do_execute_soon(function CFMFP_soon() { + do_check_false(notificationReceived); + aCallback(); + }); + }); +} diff --git a/toolkit/components/places/tests/favicons/test_expireAllFavicons.js b/toolkit/components/places/tests/favicons/test_expireAllFavicons.js new file mode 100644 index 000000000000..0dbf59f5459c --- /dev/null +++ b/toolkit/components/places/tests/favicons/test_expireAllFavicons.js @@ -0,0 +1,66 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * This file tests that favicons are correctly expired by expireAllFavicons. + */ + +//////////////////////////////////////////////////////////////////////////////// +/// Globals + +XPCOMUtils.defineLazyServiceGetter(this, "gHistory", + "@mozilla.org/browser/history;1", + "mozIAsyncHistory"); + +const TEST_PAGE_URI = NetUtil.newURI("http://example.com/"); +const BOOKMARKED_PAGE_URI = NetUtil.newURI("http://example.com/bookmarked"); + +//////////////////////////////////////////////////////////////////////////////// +/// Tests + +function run_test() { + run_next_test(); +} + +add_test(function test_expireAllFavicons() { + // Set up an observer to wait for favicons expiration to finish. + Services.obs.addObserver(function EAF_observer(aSubject, aTopic, aData) { + Services.obs.removeObserver(EAF_observer, aTopic); + + // Check that the favicons for the pages we added were removed. + checkFaviconMissingForPage(TEST_PAGE_URI, function () { + checkFaviconMissingForPage(BOOKMARKED_PAGE_URI, function () { + run_next_test(); + }); + }); + }, PlacesUtils.TOPIC_FAVICONS_EXPIRED, false); + + // Add a visited page. + gHistory.updatePlaces({ + uri: TEST_PAGE_URI, + visits: [{ + transitionType: Ci.nsINavHistoryService.TRANSITION_TYPED, + visitDate: Date.now() * 1000 + }] + }, { + handleError: function EAF_handleError(aResultCode, aPlaceInfo) { + do_throw("Unexpected error: " + aResultCode); + }, + handleResult: function EAF_handleResult(aPlaceInfo) { + PlacesUtils.favicons.setAndFetchFaviconForPage(TEST_PAGE_URI, + SMALLPNG_DATA_URI, true); + + // Add a page with a bookmark. + PlacesUtils.bookmarks.insertBookmark( + PlacesUtils.toolbarFolderId, BOOKMARKED_PAGE_URI, + PlacesUtils.bookmarks.DEFAULT_INDEX, + "Test bookmark"); + PlacesUtils.favicons.setAndFetchFaviconForPage( + BOOKMARKED_PAGE_URI, SMALLPNG_DATA_URI, true, + function EAF_onFaviconDataAvailable() { + // Start expiration only after data has been saved in the database. + PlacesUtils.favicons.expireAllFavicons(); + }); + } + }); +}); diff --git a/toolkit/components/places/tests/unit/test_favicons.js b/toolkit/components/places/tests/favicons/test_favicons.js similarity index 50% rename from toolkit/components/places/tests/unit/test_favicons.js rename to toolkit/components/places/tests/favicons/test_favicons.js index 370f046018a3..30216807f5ce 100644 --- a/toolkit/components/places/tests/unit/test_favicons.js +++ b/toolkit/components/places/tests/favicons/test_favicons.js @@ -1,195 +1,15 @@ -/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ - -// Tests for nsIFaviconService. - -// The pixel values we get in Windows are sometimes +/- 1 value compared to -// other platforms, so we need to compare against a different set of reference -// images. -let isWindows = ("@mozilla.org/windows-registry-key;1" in Cc); +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ /** - * setAndGetFaviconData() - * - * Calls setFaviconData() with the specified image data, - * and then retrieves it with getFaviconData(). - * - * @return an array: [bytes, MIME type]. + * This file tests the basic synchronous (deprecated) and asynchronous favicons + * APIs, and their interactions when they are used together. */ -function setAndGetFaviconData(aFilename, aData, aMimeType) { - let iconsvc = PlacesUtils.favicons; - let iconURI = NetUtil.newURI("http://places.test/" + aFilename); - try { - iconsvc.setFaviconData(iconURI, aData, aData.length, aMimeType, - Number.MAX_VALUE); - } catch (ex) {} - let dataURL = iconsvc.getFaviconDataAsDataURL(iconURI); - try { - iconsvc.setFaviconDataFromDataURL(iconURI, dataURL, Number.MAX_VALUE); - } catch (ex) {} - let mimeTypeOutparam = {}; - let outData = iconsvc.getFaviconData(iconURI, mimeTypeOutparam); - - return [outData, mimeTypeOutparam.value]; -} - -/** - * Retrieve and read a file, verifying the length of the returned data. - * - * @return the array of bytes read from the file. - */ -function readFileOfLength(name, expected) { - let file = do_get_file(name); - let data = readFileData(file); - do_check_eq(data.length, expected); - return data; -} - -/** - * Load a favicon file, verifying expected length. - * - * @return the loaded data to allow composing more complex checks. - */ -function setAndGetFaviconDataFromName(iconName, inMimeType, expectedLength) { - let inData = readFileOfLength(iconName, expectedLength); - let [outData, outMimeType] = setAndGetFaviconData(iconName, inData, inMimeType); - return [inData, outData, outMimeType]; -} - -/** - * Load a non-oversized favicon file, verifying expected contents and length. - */ -function check_icon_data(iconName, inMimeType, expectedLength) { - let [inData, outData, outMimeType] = - setAndGetFaviconDataFromName(iconName, inMimeType, expectedLength); - - // Ensure input and output are identical. - do_check_eq(inMimeType, outMimeType); - do_check_true(compareArrays(inData, outData)); -} - -/** - * Load an oversized favicon file, verifying expected contents and lengths - * against a translated PNG file. - * If skipContent is true, the expected and output data are not compared. - */ -function check_oversized_icon_data(iconName, inMimeType, expectedLength, skipContent) { - let [inData, outData, outMimeType] = - setAndGetFaviconDataFromName(iconName, inMimeType, expectedLength); - - // Read in the expected output. - let expectedFile = do_get_file("expected-" + iconName + ".png"); - let expectedData = readFileData(expectedFile); - - // Compare thet expected data to the actual data. - do_check_eq("image/png", outMimeType); - if (!skipContent) { - do_check_true(compareArrays(expectedData, outData)); - } -} - -function check_page_has_no_favicon(pageURI) { - try { - PlacesUtils.favicons.getFaviconForPage(pageURI); - do_throw("Page has a favicon!"); - } catch (ex if ex.result == Cr.NS_ERROR_NOT_AVAILABLE) { - // Page should have no favicon. - } catch (ex) { - do_throw("Unexpected exception " + ex); - } -} - -/* - * Done with utilities! On to the tests. - */ function run_test() { run_next_test(); } -add_test(function test_storing_a_normal_16x16_icon() { - // 16x16 png, 286 bytes. - let iconName = "favicon-normal16.png"; - let inMimeType = "image/png"; - check_icon_data(iconName, inMimeType, 286); - run_next_test(); -}); - -add_test(function test_storing_a_normal_32x32_icon() { - // 32x32 png, 344 bytes. - let iconName = "favicon-normal32.png"; - let inMimeType = "image/png"; - check_icon_data(iconName, inMimeType, 344); - run_next_test(); -}); - -add_test(function test_storing_an_oversize_16x16_icon() { - // in: 16x16 ico, 1406 bytes. - // out: 16x16 png - let iconName = "favicon-big16.ico"; - let inMimeType = "image/x-icon"; - check_oversized_icon_data(iconName, inMimeType, 1406); - run_next_test(); -}); - -add_test(function test_storing_an_oversize_4x4_icon() { - // in: 4x4 jpg, 4751 bytes. - // out: 16x16 png - let iconName = "favicon-big4.jpg"; - let inMimeType = "image/jpeg"; - check_oversized_icon_data(iconName, inMimeType, 4751); - run_next_test(); -}); - -add_test(function test_storing_an_oversize_32x32_icon() { - // in: 32x32 jpg, 3494 bytes. - // out: 16x16 png - let iconName = "favicon-big32.jpg"; - let inMimeType = "image/jpeg"; - - // Content check disabled on Windows due to problems with pixels varying - // slightly. - check_oversized_icon_data(iconName, inMimeType, 3494, isWindows); - run_next_test(); -}); - -add_test(function test_storing_an_oversize_48x48_icon() { - // in: 48x48 ico, 56646 bytes. - // (howstuffworks.com icon, contains 13 icons with sizes from 16x16 to - // 48x48 in varying depths) - // out: 16x16 png - let iconName = "favicon-big48.ico"; - let inMimeType = "image/x-icon"; - check_oversized_icon_data(iconName, inMimeType, 56646); - run_next_test(); -}); - -add_test(function test_storing_an_oversize_64x64_icon() { - // in: 64x64 png, 10698 bytes. - // out: 16x16 png - let iconName = "favicon-big64.png"; - let inMimeType = "image/png"; - check_oversized_icon_data(iconName, inMimeType, 10698); - run_next_test(); -}); - -add_test(function test_scaling_an_oversize_160x3_icon() { - // in: 160x3 jpg, 5095 bytes. - // out: 16x16 png - let iconName = "favicon-scale160x3.jpg"; - let inMimeType = "image/jpeg"; - check_oversized_icon_data(iconName, inMimeType, 5095); - run_next_test(); -}); - -add_test(function test_scaling_an_oversize_3x160_icon() { - // in: 3x160 jpg, 5059 bytes. - // out: 16x16 png - let iconName = "favicon-scale3x160.jpg"; - let inMimeType = "image/jpeg"; - check_oversized_icon_data(iconName, inMimeType, 5059); - run_next_test(); -}); - /* * The following few tests are asynchronous but share state. We bundle that * state into two arrays: `icons` and `pages`. @@ -257,16 +77,14 @@ add_test(function test_set_and_get_favicon_setup() { add_test(function test_set_and_get_favicon_getFaviconURLForPage() { let [icon0] = icons; - PlacesUtils.favicons.getFaviconURLForPage(pages[0], { - onFaviconDataAvailable: function(aURI, aDataLen, aData, aMimeType) { - do_check_true(icon0.uri.equals(aURI)); - do_check_eq(aDataLen, 0); - do_check_eq(aData.length, 0); - do_check_eq(aMimeType, ""); - run_next_test(); - }, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIFaviconDataCallback]) - }); + PlacesUtils.favicons.getFaviconURLForPage(pages[0], + function GFUFP_onFaviconDataAvailable(aURI, aDataLen, aData, aMimeType) { + do_check_true(icon0.uri.equals(aURI)); + do_check_eq(aDataLen, 0); + do_check_eq(aData.length, 0); + do_check_eq(aMimeType, ""); + run_next_test(); + }); }); add_test(function test_set_and_get_favicon_second_and_third() { @@ -315,15 +133,13 @@ add_test(function test_set_and_get_favicon_second_and_third() { add_test(function test_set_and_get_favicon_getFaviconDataForPage() { let [icon0] = icons; - PlacesUtils.favicons.getFaviconDataForPage(pages[0], { - onFaviconDataAvailable: function(aURI, aDataLen, aData, aMimeType) { - do_check_true(aURI.equals(icon0.uri)); - do_check_eq(icon0.mime, icon0.mime); - do_check_true(compareArrays(icon0.data, aData)); - do_check_eq(aDataLen, aData.length); - run_next_test(); - }, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIFaviconDataCallback]) + PlacesUtils.favicons.getFaviconDataForPage(pages[0], + function(aURI, aDataLen, aData, aMimeType) { + do_check_true(aURI.equals(icon0.uri)); + do_check_eq(icon0.mime, icon0.mime); + do_check_true(compareArrays(icon0.data, aData)); + do_check_eq(aDataLen, aData.length); + run_next_test(); }); }); @@ -419,21 +235,21 @@ add_test(function test_insert_synchronous_mints_guid() { let pageURI = NetUtil.newURI(testURI); // No icon to start with. - check_page_has_no_favicon(pageURI); + checkFaviconMissingForPage(pageURI, function () { + // Add a page with a bookmark. + insertToolbarBookmark(pageURI, "Test page"); - // Add a page with a bookmark. - insertToolbarBookmark(pageURI, "Test page"); + // Set a favicon for the page. + PlacesUtils.favicons.setFaviconUrlForPage( + pageURI, NetUtil.newURI(testIconURI) + ); - // Set a favicon for the page. - PlacesUtils.favicons.setFaviconUrlForPage( - pageURI, NetUtil.newURI(testIconURI) - ); + // Check that the URI has been set correctly. + do_check_eq(PlacesUtils.favicons.getFaviconForPage(pageURI).spec, + testIconURI); - // Check that the URI has been set correctly. - do_check_eq(PlacesUtils.favicons.getFaviconForPage(pageURI).spec, - testIconURI); - - guidForFaviconURI(testIconURI, new SingleGUIDCallback(run_next_test)); + guidForFaviconURI(testIconURI, new SingleGUIDCallback(run_next_test)); + }); }); add_test(function test_insert_asynchronous_mints_guid() { @@ -445,26 +261,21 @@ add_test(function test_insert_asynchronous_mints_guid() { let pageURI = NetUtil.newURI(testURI); // No icon to start with. - check_page_has_no_favicon(pageURI); + checkFaviconMissingForPage(pageURI, function () { + // Add a page with a bookmark. + insertToolbarBookmark(pageURI, "Other test page"); - // Add a page with a bookmark. - insertToolbarBookmark(pageURI, "Other test page"); + // Set a favicon for the page. + do_log_info("Asynchronously setting page favicon."); + PlacesUtils.favicons.setAndFetchFaviconForPage( + pageURI, iconURI, false, + function AMG_faviconDataCallback(uri, len, data, mimeType) { + do_check_true(iconURI.equals(uri)); - // Set a favicon for the page. - let faviconDataCallback = { - onFaviconDataAvailable: function (uri, len, data, mimeType) { - do_check_true(iconURI.equals(uri)); - - // Make sure there's a valid GUID. - guidForFaviconURI(iconURI.spec, new SingleGUIDCallback(run_next_test)); - } - }; - - let forceReload = false; - do_log_info("Asynchronously setting page favicon."); - PlacesUtils.favicons.setAndFetchFaviconForPage( - pageURI, iconURI, forceReload, faviconDataCallback - ); + // Make sure there's a valid GUID. + guidForFaviconURI(iconURI.spec, new SingleGUIDCallback(run_next_test)); + }); + }); }); add_test(function test_insert_asynchronous_update_preserves_guid() { @@ -477,23 +288,19 @@ add_test(function test_insert_asynchronous_update_preserves_guid() { guidForFaviconURI(iconURI.spec, new SingleGUIDCallback(function (guid) { // Set a favicon for the page... again. - let faviconDataCallback = { - onFaviconDataAvailable: function (uri, len, data, mimeType) { + do_log_info("Asynchronously re-setting page favicon."); + PlacesUtils.favicons.setAndFetchFaviconForPage( + pageURI, iconURI, true, + function UPG_faviconDataCallback(uri, len, data, mimeType) { do_check_true(iconURI.equals(uri)); // Make sure there's a valid GUID. - guidForFaviconURI(iconURI.spec, new SingleGUIDCallback(function (again) { - do_check_eq(guid, again); - run_next_test(); - })); - } - }; - - let forceReload = true; - do_log_info("Asynchronously re-setting page favicon."); - PlacesUtils.favicons.setAndFetchFaviconForPage( - pageURI, iconURI, forceReload, faviconDataCallback - ); + guidForFaviconURI(iconURI.spec, + new SingleGUIDCallback(function (again) { + do_check_eq(guid, again); + run_next_test(); + })); + }); })); }); diff --git a/toolkit/components/places/tests/favicons/test_favicons_conversions.js b/toolkit/components/places/tests/favicons/test_favicons_conversions.js new file mode 100644 index 000000000000..618558181d0d --- /dev/null +++ b/toolkit/components/places/tests/favicons/test_favicons_conversions.js @@ -0,0 +1,127 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * This file tests the image conversions done by the favicon service. + */ + +//////////////////////////////////////////////////////////////////////////////// +/// Globals + +// The pixel values we get on Windows are sometimes +/- 1 value compared to +// other platforms, so we need to skip some image content tests. +let isWindows = ("@mozilla.org/windows-registry-key;1" in Cc); + +/** + * Checks the conversion of the given test image file. + * + * @param aFileName + * File that contains the favicon image, located in the test folder. + * @param aFileMimeType + * MIME type of the image contained in the file. + * @param aFileLength + * Expected length of the file. + * @param aExpectConversion + * If false, the icon should be stored as is. If true, the expected data + * is loaded from a file named "expected-" + aFileName + ".png". + * @param aVaryOnWindows + * Indicates that the content of the converted image can be different on + * Windows and should not be checked on that platform. + * @param aCallback + * This function is called after the check finished. + */ +function checkFaviconDataConversion(aFileName, aFileMimeType, aFileLength, + aExpectConversion, aVaryOnWindows, + aCallback) { + let pageURI = NetUtil.newURI("http://places.test/page/" + aFileName); + let faviconURI = NetUtil.newURI("http://places.test/icon/" + aFileName); + let fileData = readFileOfLength(aFileName, aFileLength); + + PlacesUtils.favicons.replaceFaviconData(faviconURI, fileData, fileData.length, + aFileMimeType); + PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, faviconURI, true, + function CFDC_verify(aURI, aDataLen, aData, aMimeType) { + if (!aExpectConversion) { + do_check_true(compareArrays(aData, fileData)); + do_check_eq(aMimeType, aFileMimeType); + } else { + if (!aVaryOnWindows || !isWindows) { + let expectedFile = do_get_file("expected-" + aFileName + ".png"); + do_check_true(compareArrays(aData, readFileData(expectedFile))); + } + do_check_eq(aMimeType, "image/png"); + } + + aCallback(); + }); +} + +//////////////////////////////////////////////////////////////////////////////// +/// Tests + +function run_test() { + run_next_test(); +} + +add_test(function test_storing_a_normal_16x16_icon() { + // 16x16 png, 286 bytes. + checkFaviconDataConversion("favicon-normal16.png", "image/png", 286, + false, false, run_next_test); +}); + +add_test(function test_storing_a_normal_32x32_icon() { + // 32x32 png, 344 bytes. + checkFaviconDataConversion("favicon-normal32.png", "image/png", 344, + false, false, run_next_test); +}); + +add_test(function test_storing_an_oversize_16x16_icon() { + // in: 16x16 ico, 1406 bytes. + // out: 16x16 png + checkFaviconDataConversion("favicon-big16.ico", "image/x-icon", 1406, + true, false, run_next_test); +}); + +add_test(function test_storing_an_oversize_4x4_icon() { + // in: 4x4 jpg, 4751 bytes. + // out: 16x16 png + checkFaviconDataConversion("favicon-big4.jpg", "image/jpeg", 4751, + true, false, run_next_test); +}); + +add_test(function test_storing_an_oversize_32x32_icon() { + // in: 32x32 jpg, 3494 bytes. + // out: 16x16 png + checkFaviconDataConversion("favicon-big32.jpg", "image/jpeg", 3494, + true, true, run_next_test); +}); + +add_test(function test_storing_an_oversize_48x48_icon() { + // in: 48x48 ico, 56646 bytes. + // (howstuffworks.com icon, contains 13 icons with sizes from 16x16 to + // 48x48 in varying depths) + // out: 16x16 png + checkFaviconDataConversion("favicon-big48.ico", "image/x-icon", 56646, + true, false, run_next_test); +}); + +add_test(function test_storing_an_oversize_64x64_icon() { + // in: 64x64 png, 10698 bytes. + // out: 16x16 png + checkFaviconDataConversion("favicon-big64.png", "image/png", 10698, + true, false, run_next_test); +}); + +add_test(function test_scaling_an_oversize_160x3_icon() { + // in: 160x3 jpg, 5095 bytes. + // out: 16x16 png + checkFaviconDataConversion("favicon-scale160x3.jpg", "image/jpeg", 5095, + true, false, run_next_test); +}); + +add_test(function test_scaling_an_oversize_3x160_icon() { + // in: 3x160 jpg, 5059 bytes. + // out: 16x16 png + checkFaviconDataConversion("favicon-scale3x160.jpg", "image/jpeg", 5059, + true, false, run_next_test); +}); diff --git a/toolkit/components/places/tests/unit/test_moz-anno_favicon_mime_type.js b/toolkit/components/places/tests/favicons/test_moz-anno_favicon_mime_type.js similarity index 97% rename from toolkit/components/places/tests/unit/test_moz-anno_favicon_mime_type.js rename to toolkit/components/places/tests/favicons/test_moz-anno_favicon_mime_type.js index 0aa38e1274c3..512a6c9a0298 100644 --- a/toolkit/components/places/tests/unit/test_moz-anno_favicon_mime_type.js +++ b/toolkit/components/places/tests/favicons/test_moz-anno_favicon_mime_type.js @@ -107,8 +107,8 @@ function run_test() // Test that the content type of a favicon we add ends up being image/png. let (testURI = uri("http://mozilla.org/")) { // Add the data before opening - fs.setFaviconDataFromDataURL(testURI, testFaviconData, - (Date.now() + 60 * 60 * 24 * 1000) * 1000); + fs.replaceFaviconDataFromDataURL(testURI, testFaviconData, + (Date.now() + 60 * 60 * 24 * 1000) * 1000); // Open the channel let channel = ios.newChannel(moz_anno_favicon_prefix + testURI.spec, null, diff --git a/toolkit/components/places/tests/favicons/test_query_result_favicon_changed_on_child.js b/toolkit/components/places/tests/favicons/test_query_result_favicon_changed_on_child.js new file mode 100644 index 000000000000..2161b535e275 --- /dev/null +++ b/toolkit/components/places/tests/favicons/test_query_result_favicon_changed_on_child.js @@ -0,0 +1,84 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Test for bug 451499 : + * Wrong folder icon appears on smart bookmarks. + */ + +//////////////////////////////////////////////////////////////////////////////// +/// Globals + +const PAGE_URI = NetUtil.newURI("http://example.com/test_query_result"); + +//////////////////////////////////////////////////////////////////////////////// +/// Tests + +function run_test() +{ + run_next_test(); +} + +add_test(function test_query_result_favicon_changed_on_child() +{ + // Bookmark our test page, so it will appear in the query resultset. + let testBookmark = PlacesUtils.bookmarks.insertBookmark( + PlacesUtils.bookmarksMenuFolderId, + PAGE_URI, + PlacesUtils.bookmarks.DEFAULT_INDEX, + "test_bookmark"); + + // Get the last 10 bookmarks added to the menu or the toolbar. + let query = PlacesUtils.history.getNewQuery(); + query.setFolders([PlacesUtils.bookmarksMenuFolderId, + PlacesUtils.toolbarFolderId], 2); + + let options = PlacesUtils.history.getNewQueryOptions(); + options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; + options.maxResults = 10; + options.excludeQueries = 1; + options.sortingMode = options.SORT_BY_DATE_DESCENDING; + + let result = PlacesUtils.history.executeQuery(query, options); + let resultObserver = { + __proto__: NavHistoryResultObserver.prototype, + containerStateChanged: function QRFCOC_containerStateChanged(aContainerNode, + aOldState, + aNewState) { + if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED) { + // We set a favicon on PAGE_URI while the container is open. The + // favicon for the page must have data associated with it in order for + // the icon changed notifications to be sent, so we use a valid image + // data URI. + PlacesUtils.favicons.setAndFetchFaviconForPage(PAGE_URI, + SMALLPNG_DATA_URI, + false); + } + }, + nodeIconChanged: function QRFCOC_nodeIconChanged(aNode) { + do_throw("The icon should be set only for the page," + + " not for the containing query."); + } + }; + result.addObserver(resultObserver, false); + + waitForFaviconChanged(PAGE_URI, SMALLPNG_DATA_URI, + function QRFCOC_faviconChanged() { + // We must wait for the asynchronous database thread to finish the + // operation, and then for the main thread to process any pending + // notifications that came from the asynchronous thread, before we can be + // sure that nodeIconChanged was not invoked in the meantime. + waitForAsyncUpdates(function QRFCOC_asyncUpdates() { + do_execute_soon(function QRFCOC_soon() { + result.removeObserver(resultObserver); + + // Free the resources immediately. + result.root.containerOpen = false; + run_next_test(); + }); + }); + }); + + // Open the container and wait for containerStateChanged. + result.root.containerOpen = true; +}); diff --git a/toolkit/components/places/tests/unit/test_doReplaceFaviconData.js b/toolkit/components/places/tests/favicons/test_replaceFaviconData.js similarity index 76% rename from toolkit/components/places/tests/unit/test_doReplaceFaviconData.js rename to toolkit/components/places/tests/favicons/test_replaceFaviconData.js index 85010904e1b8..5aeded0beda9 100644 --- a/toolkit/components/places/tests/unit/test_doReplaceFaviconData.js +++ b/toolkit/components/places/tests/favicons/test_replaceFaviconData.js @@ -58,17 +58,6 @@ function addVisit(aURI) { 0); } -function checkAddSucceeded(pageURI, mimetype, data) { - let savedFaviconURI = iconsvc.getFaviconForPage(pageURI); - let outMimeType = {}; - let outData = iconsvc.getFaviconData(savedFaviconURI, outMimeType, {}); - - // Ensure input and output are identical - do_check_eq(mimetype, outMimeType.value); - do_check_true(compareArrays(data, outData)); - do_check_guid_for_uri(pageURI); -} - function checkCallbackSucceeded(callbackMimetype, callbackData, sourceMimetype, sourceData) { do_check_eq(callbackMimetype, sourceMimetype); do_check_true(compareArrays(callbackData, sourceData)); @@ -93,10 +82,12 @@ add_test(function test_replaceFaviconData_validHistoryURI() { iconsvc.setAndFetchFaviconForPage(pageURI, favicon.uri, true, function test_replaceFaviconData_validHistoryURI_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, favicon.mimetype, favicon.data); - checkAddSucceeded(pageURI, favicon.mimetype, favicon.data); - - favicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, favicon.mimetype, favicon.data, + function test_replaceFaviconData_validHistoryURI_callback() { + favicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); @@ -116,11 +107,13 @@ add_test(function test_replaceFaviconData_overrideDefaultFavicon() { pageURI, firstFavicon.uri, true, function test_replaceFaviconData_overrideDefaultFavicon_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data); - checkAddSucceeded(pageURI, secondFavicon.mimetype, secondFavicon.data); - - firstFavicon.file.remove(false); - secondFavicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, secondFavicon.mimetype, secondFavicon.data, + function test_replaceFaviconData_overrideDefaultFavicon_callback() { + firstFavicon.file.remove(false); + secondFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); @@ -137,17 +130,22 @@ add_test(function test_replaceFaviconData_replaceExisting() { pageURI, firstFavicon.uri, true, function test_replaceFaviconData_replaceExisting_firstSet_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, firstFavicon.mimetype, firstFavicon.data); - checkAddSucceeded(pageURI, firstFavicon.mimetype, firstFavicon.data); - - iconsvc.replaceFaviconData( - firstFavicon.uri, secondFavicon.data, secondFavicon.data.length, - secondFavicon.mimetype); - waitForAsyncUpdates(function() { - checkAddSucceeded(pageURI, secondFavicon.mimetype, secondFavicon.data); - firstFavicon.file.remove(false); - secondFavicon.file.remove(false); - waitForClearHistory(run_next_test); - }); + checkFaviconDataForPage( + pageURI, firstFavicon.mimetype, firstFavicon.data, + function test_replaceFaviconData_overrideDefaultFavicon_firstCallback() { + iconsvc.replaceFaviconData( + firstFavicon.uri, secondFavicon.data, secondFavicon.data.length, + secondFavicon.mimetype); + waitForAsyncUpdates(function() { + checkFaviconDataForPage( + pageURI, secondFavicon.mimetype, secondFavicon.data, + function test_replaceFaviconData_overrideDefaultFavicon_secondCallback() { + firstFavicon.file.remove(false); + secondFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); + }); + }); }); }); @@ -167,11 +165,13 @@ add_test(function test_replaceFaviconData_unrelatedReplace() { pageURI, favicon.uri, true, function test_replaceFaviconData_unrelatedReplace_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, favicon.mimetype, favicon.data); - checkAddSucceeded(pageURI, favicon.mimetype, favicon.data); - - favicon.file.remove(false); - unrelatedFavicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, favicon.mimetype, favicon.data, + function test_replaceFaviconData_unrelatedReplace_callback() { + favicon.file.remove(false); + unrelatedFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); @@ -234,10 +234,12 @@ add_test(function test_replaceFaviconData_twiceReplace() { pageURI, firstFavicon.uri, true, function test_replaceFaviconData_twiceReplace_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data); - checkAddSucceeded(pageURI, secondFavicon.mimetype, secondFavicon.data); - - firstFavicon.file.remove(false); - secondFavicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, secondFavicon.mimetype, secondFavicon.data, + function test_replaceFaviconData_twiceReplace_callback() { + firstFavicon.file.remove(false); + secondFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); diff --git a/toolkit/components/places/tests/unit/test_doReplaceFaviconDataFromDataURL.js b/toolkit/components/places/tests/favicons/test_replaceFaviconDataFromDataURL.js similarity index 76% rename from toolkit/components/places/tests/unit/test_doReplaceFaviconDataFromDataURL.js rename to toolkit/components/places/tests/favicons/test_replaceFaviconDataFromDataURL.js index e4fdb99b84a9..a8526faad10e 100644 --- a/toolkit/components/places/tests/unit/test_doReplaceFaviconDataFromDataURL.js +++ b/toolkit/components/places/tests/favicons/test_replaceFaviconDataFromDataURL.js @@ -62,17 +62,6 @@ function addVisit(aURI) { 0); } -function checkAddSucceeded(pageURI, mimetype, data) { - let savedFaviconURI = iconsvc.getFaviconForPage(pageURI); - let outMimeType = {}; - let outData = iconsvc.getFaviconData(savedFaviconURI, outMimeType, {}); - - // Ensure input and output are identical - do_check_eq(mimetype, outMimeType.value); - do_check_true(compareArrays(data, outData)); - do_check_guid_for_uri(pageURI); -} - function checkCallbackSucceeded(callbackMimetype, callbackData, sourceMimetype, sourceData) { do_check_eq(callbackMimetype, sourceMimetype); do_check_true(compareArrays(callbackData, sourceData)); @@ -95,10 +84,12 @@ add_test(function test_replaceFaviconDataFromDataURL_validHistoryURI() { iconsvc.setAndFetchFaviconForPage(pageURI, favicon.uri, true, function test_replaceFaviconDataFromDataURL_validHistoryURI_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, favicon.mimetype, favicon.data); - checkAddSucceeded(pageURI, favicon.mimetype, favicon.data); - - favicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, favicon.mimetype, favicon.data, + function test_replaceFaviconDataFromDataURL_validHistoryURI_callback() { + favicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); @@ -116,11 +107,13 @@ add_test(function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon() { pageURI, firstFavicon.uri, true, function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data); - checkAddSucceeded(pageURI, secondFavicon.mimetype, secondFavicon.data); - - firstFavicon.file.remove(false); - secondFavicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, secondFavicon.mimetype, secondFavicon.data, + function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon_callback() { + firstFavicon.file.remove(false); + secondFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); @@ -137,15 +130,18 @@ add_test(function test_replaceFaviconDataFromDataURL_replaceExisting() { pageURI, firstFavicon.uri, true, function test_replaceFaviconDataFromDataURL_replaceExisting_firstSet_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, firstFavicon.mimetype, firstFavicon.data); - checkAddSucceeded(pageURI, firstFavicon.mimetype, firstFavicon.data); - - iconsvc.replaceFaviconDataFromDataURL(firstFavicon.uri, createDataURLForFavicon(secondFavicon)); - waitForAsyncUpdates(function() { - checkAddSucceeded(pageURI, secondFavicon.mimetype, secondFavicon.data); - firstFavicon.file.remove(false); - secondFavicon.file.remove(false); - waitForClearHistory(run_next_test); - }); + checkFaviconDataForPage( + pageURI, firstFavicon.mimetype, firstFavicon.data, + function test_replaceFaviconDataFromDataURL_replaceExisting_firstCallback() { + iconsvc.replaceFaviconDataFromDataURL(firstFavicon.uri, createDataURLForFavicon(secondFavicon)); + checkFaviconDataForPage( + pageURI, secondFavicon.mimetype, secondFavicon.data, + function test_replaceFaviconDataFromDataURL_replaceExisting_secondCallback() { + firstFavicon.file.remove(false); + secondFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); + }); }); }); @@ -163,11 +159,13 @@ add_test(function test_replaceFaviconDataFromDataURL_unrelatedReplace() { pageURI, favicon.uri, true, function test_replaceFaviconDataFromDataURL_unrelatedReplace_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, favicon.mimetype, favicon.data); - checkAddSucceeded(pageURI, favicon.mimetype, favicon.data); - - favicon.file.remove(false); - unrelatedFavicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, favicon.mimetype, favicon.data, + function test_replaceFaviconDataFromDataURL_unrelatedReplace_callback() { + favicon.file.remove(false); + unrelatedFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); @@ -214,11 +212,13 @@ add_test(function test_replaceFaviconDataFromDataURL_twiceReplace() { pageURI, firstFavicon.uri, true, function test_replaceFaviconDataFromDataURL_twiceReplace_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data); - checkAddSucceeded(pageURI, secondFavicon.mimetype, secondFavicon.data); - - firstFavicon.file.remove(false); - secondFavicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, secondFavicon.mimetype, secondFavicon.data, + function test_replaceFaviconDataFromDataURL_twiceReplace_callback() { + firstFavicon.file.remove(false); + secondFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); @@ -238,17 +238,19 @@ add_test(function test_replaceFaviconDataFromDataURL_afterRegularAssign() { iconsvc.setAndFetchFaviconForPage( pageURI, firstFavicon.uri, true, - function test_replaceFaviconDataFromDataURL_twiceReplace_check(aURI, aDataLen, aData, aMimeType) { + function test_replaceFaviconDataFromDataURL_afterRegularAssign_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data); - checkAddSucceeded(pageURI, secondFavicon.mimetype, secondFavicon.data); - - firstFavicon.file.remove(false); - secondFavicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, secondFavicon.mimetype, secondFavicon.data, + function test_replaceFaviconDataFromDataURL_afterRegularAssign_callback() { + firstFavicon.file.remove(false); + secondFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); -add_test(function test_replaceFaviconDataFromDataURL_afterRegularAssign() { +add_test(function test_replaceFaviconDataFromDataURL_beforeRegularAssign() { do_log_info("test replaceFaviconDataFromDataURL before replaceFaviconData"); let pageURI = uri("http://test7.bar/"); @@ -264,13 +266,15 @@ add_test(function test_replaceFaviconDataFromDataURL_afterRegularAssign() { iconsvc.setAndFetchFaviconForPage( pageURI, firstFavicon.uri, true, - function test_replaceFaviconDataFromDataURL_twiceReplace_check(aURI, aDataLen, aData, aMimeType) { + function test_replaceFaviconDataFromDataURL_beforeRegularAssign_check(aURI, aDataLen, aData, aMimeType) { checkCallbackSucceeded(aMimeType, aData, secondFavicon.mimetype, secondFavicon.data); - checkAddSucceeded(pageURI, secondFavicon.mimetype, secondFavicon.data); - - firstFavicon.file.remove(false); - secondFavicon.file.remove(false); - waitForClearHistory(run_next_test); + checkFaviconDataForPage( + pageURI, secondFavicon.mimetype, secondFavicon.data, + function test_replaceFaviconDataFromDataURL_beforeRegularAssign_callback() { + firstFavicon.file.remove(false); + secondFavicon.file.remove(false); + waitForClearHistory(run_next_test); + }); }); }); diff --git a/toolkit/components/places/tests/favicons/test_setAndFetchFaviconForPage.js b/toolkit/components/places/tests/favicons/test_setAndFetchFaviconForPage.js new file mode 100644 index 000000000000..5b0aaf2d92fb --- /dev/null +++ b/toolkit/components/places/tests/favicons/test_setAndFetchFaviconForPage.js @@ -0,0 +1,106 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * This file tests the normal operation of setAndFetchFaviconForPage. + */ + +//////////////////////////////////////////////////////////////////////////////// +/// Globals + +const FAVICON_URI = NetUtil.newURI(do_get_file("favicon-normal32.png")); +const FAVICON_DATA = readFileData(do_get_file("favicon-normal32.png")); +const FAVICON_MIMETYPE = "image/png"; + +//////////////////////////////////////////////////////////////////////////////// +/// Tests + +function run_test() +{ + // Check that the favicon loaded correctly before starting the actual tests. + do_check_eq(FAVICON_DATA.length, 344); + run_next_test(); +} + +add_test(function test_normal() +{ + let pageURI = NetUtil.newURI("http://example.com/normal"); + waitForFaviconChanged(pageURI, FAVICON_URI, + function test_normal_callback() { + do_check_true(isUrlHidden(pageURI)); + do_check_eq(frecencyForUrl(pageURI), 0); + checkFaviconDataForPage(pageURI, FAVICON_MIMETYPE, FAVICON_DATA, + run_next_test); + }); + PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, FAVICON_URI, true); +}); + +add_test(function test_aboutURI_bookmarked() +{ + let pageURI = NetUtil.newURI("about:testAboutURI_bookmarked"); + waitForFaviconChanged(pageURI, FAVICON_URI, + function test_aboutURI_bookmarked_callback() { + checkFaviconDataForPage(pageURI, FAVICON_MIMETYPE, FAVICON_DATA, + run_next_test); + }); + + PlacesUtils.bookmarks.insertBookmark( + PlacesUtils.unfiledBookmarksFolderId, pageURI, + PlacesUtils.bookmarks.DEFAULT_INDEX, pageURI.spec); + PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, FAVICON_URI, true); +}); + +add_test(function test_privateBrowsing_bookmarked() +{ + if (!"@mozilla.org/privatebrowsing;1" in Cc) { + run_next_next(); + return; + } + + let pageURI = NetUtil.newURI("http://example.com/privateBrowsing_bookmarked"); + waitForFaviconChanged(pageURI, FAVICON_URI, + function test_privateBrowsing_bookmarked_callback() { + checkFaviconDataForPage(pageURI, FAVICON_MIMETYPE, FAVICON_DATA, + run_next_test); + }); + + // Enable private browsing while changing the favicon. + let pb = Cc["@mozilla.org/privatebrowsing;1"] + .getService(Ci.nsIPrivateBrowsingService); + Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", + true); + pb.privateBrowsingEnabled = true; + + PlacesUtils.bookmarks.insertBookmark( + PlacesUtils.unfiledBookmarksFolderId, pageURI, + PlacesUtils.bookmarks.DEFAULT_INDEX, pageURI.spec); + PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, FAVICON_URI, true); + + // The setAndFetchFaviconForPage function calls CanAddURI synchronously, + // thus we can exit Private Browsing Mode immediately. + pb.privateBrowsingEnabled = false; + Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session"); +}); + +add_test(function test_disabledHistory_bookmarked() +{ + let pageURI = NetUtil.newURI("http://example.com/disabledHistory_bookmarked"); + waitForFaviconChanged(pageURI, FAVICON_URI, + function test_disabledHistory_bookmarked_callback() { + checkFaviconDataForPage(pageURI, FAVICON_MIMETYPE, FAVICON_DATA, + run_next_test); + }); + + // Disable history while changing the favicon. + Services.prefs.setBoolPref("places.history.enabled", false); + + PlacesUtils.bookmarks.insertBookmark( + PlacesUtils.unfiledBookmarksFolderId, pageURI, + PlacesUtils.bookmarks.DEFAULT_INDEX, pageURI.spec); + PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, FAVICON_URI, true); + + // The setAndFetchFaviconForPage function calls CanAddURI synchronously, thus + // we can set the preference back to true immediately. We don't clear the + // preference because not all products enable Places by default. + Services.prefs.setBoolPref("places.history.enabled", true); +}); diff --git a/toolkit/components/places/tests/favicons/test_setAndFetchFaviconForPage_failures.js b/toolkit/components/places/tests/favicons/test_setAndFetchFaviconForPage_failures.js new file mode 100644 index 000000000000..3ebeb07221e5 --- /dev/null +++ b/toolkit/components/places/tests/favicons/test_setAndFetchFaviconForPage_failures.js @@ -0,0 +1,143 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * This file tests setAndFetchFaviconForPage when it is called with invalid + * arguments, and when no favicon is stored for the given arguments. + */ + +//////////////////////////////////////////////////////////////////////////////// +/// Globals + +const FAVICON_URI = NetUtil.newURI(do_get_file("favicon-normal16.png")); +const LAST_PAGE_URI = NetUtil.newURI("http://example.com/verification"); +const LAST_FAVICON_URI = NetUtil.newURI(do_get_file("favicon-normal32.png")); + +//////////////////////////////////////////////////////////////////////////////// +/// Tests + +function run_test() +{ + // We run all the tests that follow, but only the last one should raise the + // onPageChanged notification, executing the waitForFaviconChanged callback. + waitForFaviconChanged(LAST_PAGE_URI, LAST_FAVICON_URI, + function final_callback() { + // Check that only one record corresponding to the last favicon is present. + let resultCount = 0; + let stmt = DBConn().createAsyncStatement("SELECT url FROM moz_favicons"); + stmt.executeAsync({ + handleResult: function final_handleResult(aResultSet) { + for (let row; (row = aResultSet.getNextRow()); ) { + do_check_eq(LAST_FAVICON_URI.spec, row.getResultByIndex(0)); + resultCount++; + } + }, + handleError: function final_handleError(aError) { + do_throw("Unexpected error (" + aError.result + "): " + aError.message); + }, + handleCompletion: function final_handleCompletion(aReason) { + do_check_eq(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason); + do_check_eq(1, resultCount); + run_next_test(); + } + }); + stmt.finalize(); + }); + + run_next_test(); +} + +add_test(function test_null_pageURI() +{ + try { + PlacesUtils.favicons.setAndFetchFaviconForPage( + null, + FAVICON_URI, true); + do_throw("Exception expected because aPageURI is null."); + } catch (ex) { + // We expected an exception. + } + + run_next_test(); +}); + +add_test(function test_null_faviconURI() +{ + try { + PlacesUtils.favicons.setAndFetchFaviconForPage( + NetUtil.newURI("http://example.com/null_faviconURI"), + null, true); + do_throw("Exception expected because aFaviconURI is null."); + } catch (ex) { + // We expected an exception. + } + + run_next_test(); +}); + +add_test(function test_aboutURI() +{ + PlacesUtils.favicons.setAndFetchFaviconForPage( + NetUtil.newURI("about:testAboutURI"), + FAVICON_URI, true); + + run_next_test(); +}); + +add_test(function test_privateBrowsing_nonBookmarkedURI() +{ + if (!"@mozilla.org/privatebrowsing;1" in Cc) { + run_next_test(); + return; + } + + let pb = Cc["@mozilla.org/privatebrowsing;1"] + .getService(Ci.nsIPrivateBrowsingService); + Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session", + true); + pb.privateBrowsingEnabled = true; + + PlacesUtils.favicons.setAndFetchFaviconForPage( + NetUtil.newURI("http://example.com/privateBrowsing"), + FAVICON_URI, true); + + // The setAndFetchFaviconForPage function calls CanAddURI synchronously, + // thus we can exit Private Browsing Mode immediately. + pb.privateBrowsingEnabled = false; + Services.prefs.clearUserPref("browser.privatebrowsing.keep_current_session"); + run_next_test(); +}); + +add_test(function test_disabledHistory() +{ + Services.prefs.setBoolPref("places.history.enabled", false); + + PlacesUtils.favicons.setAndFetchFaviconForPage( + NetUtil.newURI("http://example.com/disabledHistory"), + FAVICON_URI, true); + + // The setAndFetchFaviconForPage function calls CanAddURI synchronously, thus + // we can set the preference back to true immediately . We don't clear the + // preference because not all products enable Places by default. + Services.prefs.setBoolPref("places.history.enabled", true); + run_next_test(); +}); + +add_test(function test_errorIcon() +{ + PlacesUtils.favicons.setAndFetchFaviconForPage( + NetUtil.newURI("http://example.com/errorIcon"), + FAVICON_ERRORPAGE_URI, true); + + run_next_test(); +}); + +add_test(function test_finalVerification() +{ + // This is the only test that should cause the waitForFaviconChanged callback + // we set up earlier to be invoked. In turn, the callback will invoke + // run_next_test() causing the tests to finish. + PlacesUtils.favicons.setAndFetchFaviconForPage( + LAST_PAGE_URI, + LAST_FAVICON_URI, true); +}); diff --git a/toolkit/components/places/tests/favicons/xpcshell.ini b/toolkit/components/places/tests/favicons/xpcshell.ini new file mode 100644 index 000000000000..9048836dc620 --- /dev/null +++ b/toolkit/components/places/tests/favicons/xpcshell.ini @@ -0,0 +1,19 @@ +[DEFAULT] +head = head_favicons.js +tail = + +[test_expireAllFavicons.js] +[test_favicons.js] +# Bug 676989: test fails consistently on Android +fail-if = os == "android" +[test_favicons_conversions.js] +# Bug 676989: test fails consistently on Android +fail-if = os == "android" +[test_moz-anno_favicon_mime_type.js] +[test_query_result_favicon_changed_on_child.js] +[test_replaceFaviconData.js] +[test_replaceFaviconDataFromDataURL.js] +[test_setAndFetchFaviconForPage.js] +[test_setAndFetchFaviconForPage_failures.js] +# Bug 676989: test fails consistently on Android +fail-if = os == "android" diff --git a/toolkit/components/places/tests/head_common.js b/toolkit/components/places/tests/head_common.js index e1924d3dbb2b..72512edbc836 100644 --- a/toolkit/components/places/tests/head_common.js +++ b/toolkit/components/places/tests/head_common.js @@ -51,10 +51,6 @@ const TRANSITION_REDIRECT_PERMANENT = Ci.nsINavHistoryService.TRANSITION_REDIREC const TRANSITION_REDIRECT_TEMPORARY = Ci.nsINavHistoryService.TRANSITION_REDIRECT_TEMPORARY; const TRANSITION_DOWNLOAD = Ci.nsINavHistoryService.TRANSITION_DOWNLOAD; -// This error icon must stay in sync with FAVICON_ERRORPAGE_URL in -// nsIFaviconService.idl, aboutCertError.xhtml and netError.xhtml. -const FAVICON_ERRORPAGE_URL = "chrome://global/skin/icons/warning-16.png"; - const TITLE_LENGTH_MAX = 4096; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); @@ -75,6 +71,11 @@ XPCOMUtils.defineLazyGetter(this, "FileUtils", function() { }); Cu.import("resource://gre/modules/PlacesUtils.jsm"); +XPCOMUtils.defineLazyGetter(this, "SMALLPNG_DATA_URI", function() { + return NetUtil.newURI( + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAA" + + "AAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg=="); +}); function LOG(aMsg) { aMsg = ("*** PLACES TESTS: " + aMsg); @@ -182,6 +183,22 @@ function readFileData(aFile) { return bytes; } +/** + * Reads the data from the named file, verifying the expected file length. + * + * @param aFileName + * This file should be located in the same folder as the test. + * @param aExpectedLength + * Expected length of the file. + * + * @return The array of bytes read from the file. + */ +function readFileOfLength(aFileName, aExpectedLength) { + let data = readFileData(do_get_file(aFileName)); + do_check_eq(data.length, aExpectedLength); + return data; +} + /** * Compares two arrays, and returns true if they are equal. @@ -821,3 +838,35 @@ NavHistoryObserver.prototype = { Ci.nsINavHistoryObserver, ]) }; + +/** + * Generic nsINavHistoryResultObserver that doesn't implement anything, but + * provides dummy methods to prevent errors about an object not having a certain + * method. + */ +function NavHistoryResultObserver() {} + +NavHistoryResultObserver.prototype = { + batching: function () {}, + containerClosed: function () {}, + containerOpened: function () {}, + containerStateChanged: function () {}, + invalidateContainer: function () {}, + nodeAnnotationChanged: function () {}, + nodeDateAddedChanged: function () {}, + nodeHistoryDetailsChanged: function () {}, + nodeIconChanged: function () {}, + nodeInserted: function () {}, + nodeKeywordChanged: function () {}, + nodeLastModifiedChanged: function () {}, + nodeMoved: function () {}, + nodeRemoved: function () {}, + nodeReplaced: function () {}, + nodeTagsChanged: function () {}, + nodeTitleChanged: function () {}, + nodeURIChanged: function () {}, + sortingChanged: function () {}, + QueryInterface: XPCOMUtils.generateQI([ + Ci.nsINavHistoryResultObserver, + ]) +}; diff --git a/toolkit/components/places/tests/queries/head_queries.js b/toolkit/components/places/tests/queries/head_queries.js index 531eccbf40c9..5d109b34320a 100644 --- a/toolkit/components/places/tests/queries/head_queries.js +++ b/toolkit/components/places/tests/queries/head_queries.js @@ -177,20 +177,6 @@ function populateDB(aArray) { } } - if (qdata.isFavicon) { - // Not planning on doing deep testing of favIcon service so these two - // calls should be sufficient to get favicons into the database - try { - PlacesUtils.favicons.setFaviconData(uri(qdata.faviconURI), - qdata.favicon, - qdata.faviconLen, - qdata.faviconMimeType, - qdata.faviconExpiration); - } catch (ex) {} - PlacesUtils.favicons.setFaviconUrlForPage(uri(qdata.uri), - uri(qdata.faviconURI)); - } - if (qdata.isFolder) { let folderId = PlacesUtils.bookmarks.createFolder(qdata.parentFolder, qdata.title, @@ -286,12 +272,6 @@ function queryData(obj) { this.annoMimeType = obj.annoMimeType ? obj.annoMimeType : ""; this.isTag = obj.isTag ? obj.isTag : false; this.tagArray = obj.tagArray ? obj.tagArray : null; - this.isFavicon = obj.isFavicon ? obj.isFavicon : false; - this.faviconURI = obj.faviconURI ? obj.faviconURI : ""; - this.faviconLen = obj.faviconLen ? obj.faviconLen : 0; - this.faviconMimeType = obj.faviconMimeType ? obj.faviconMimeType : ""; - this.faviconExpiration = obj.faviconExpiration ? - obj.faviconExpiration : futureday; this.isLivemark = obj.isLivemark ? obj.isLivemark : false; this.parentFolder = obj.parentFolder ? obj.parentFolder : PlacesUtils.placesRootId; diff --git a/toolkit/components/places/tests/unit/test_404630.js b/toolkit/components/places/tests/unit/test_404630.js deleted file mode 100644 index e1993155be0e..000000000000 --- a/toolkit/components/places/tests/unit/test_404630.js +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Google Inc. - * Portions created by the Initial Developer are Copyright (C) 2005 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Seth Spitzer - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -function run_test() { - let exceptionCaught = false; - try { - PlacesUtils.favicons.setAndLoadFaviconForPage( - null, uri("http://www.mozilla.com/favicon.ico"), false - ); - } catch (ex) { - exceptionCaught = true; - } - do_check_true(exceptionCaught, "should throw because page param is null"); - - exceptionCaught = false; - try { - PlacesUtils.favicons.setAndLoadFaviconForPage( - uri("http://www.mozilla.com"), null, false - ); - do_throw("should throw because favicon param is null"); - } catch (ex) { - exceptionCaught = true; - } - do_check_true(exceptionCaught, "should throw because page param is null"); -} diff --git a/toolkit/components/places/tests/unit/test_451499.js b/toolkit/components/places/tests/unit/test_451499.js deleted file mode 100644 index f59852427442..000000000000 --- a/toolkit/components/places/tests/unit/test_451499.js +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Bug 451499 code. - * - * The Initial Developer of the Original Code is the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Marco Bonardo (Original Author) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -// Get services -try { - var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); - var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); - var iconsvc = Cc["@mozilla.org/browser/favicon-service;1"]. - getService(Ci.nsIFaviconService); -} catch(ex) { - do_throw("Could not get services\n"); -} - -/* - * readFileData() - * - * Reads the data from the specified nsIFile, and returns an array of bytes. - */ -function readFileData(aFile) { - var inputStream = Cc["@mozilla.org/network/file-input-stream;1"]. - createInstance(Ci.nsIFileInputStream); - // init the stream as RD_ONLY, -1 == default permissions. - inputStream.init(aFile, 0x01, -1, null); - var size = inputStream.available(); - - // use a binary input stream to grab the bytes. - var bis = Cc["@mozilla.org/binaryinputstream;1"]. - createInstance(Ci.nsIBinaryInputStream); - bis.setInputStream(inputStream); - - var bytes = bis.readByteArray(size); - - if (size != bytes.length) - throw "Didn't read expected number of bytes"; - - return bytes; -} - -var result; -var resultObserver = { - itemChanged: function(item) { - // The favicon should not be set on the containing query. - if (item.uri.substr(0,5) == "place") - print("Testing itemChanged on: " + item.uri); - do_check_eq(item.icon.spec, null); - } -}; - -// main -function run_test() { - var testURI = uri("http://places.test/"); - - // Setup a real favicon data - var iconName = "favicon-normal16.png"; - var iconURI = uri("http://places.test/" + iconName); - var iconMimeType = "image/png"; - var iconFile = do_get_file(iconName); - var iconData = readFileData(iconFile); - do_check_eq(iconData.length, 286); - iconsvc.setFaviconData(iconURI, - iconData, iconData.length, iconMimeType, - Number.MAX_VALUE); - - // Bookmark our test page, so it will appear in the query resultset - var testBookmark = bmsvc.insertBookmark(bmsvc.bookmarksMenuFolder, - testURI, - bmsvc.DEFAULT_INDEX, - "foo"); - - // Get the last 10 bookmarks added to menu or toolbar - var options = histsvc.getNewQueryOptions(); - var query = histsvc.getNewQuery(); - query.setFolders([bmsvc.bookmarksMenuFolder, bmsvc.toolbarFolder], 2); - options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS; - options.maxResults = 10; - options.excludeQueries = 1; - options.sortingMode = options.SORT_BY_DATE_DESCENDING; - result = histsvc.executeQuery(query, options); - result.addObserver(resultObserver, false); - - var root = result.root; - root.containerOpen = true; - - // We set a favicon on testURI while the container is open. - // This favicon should be setup only for this website, not for the containing - // query, this will be checked by the viewer - iconsvc.setFaviconUrlForPage(testURI, iconURI); - - do_test_pending(); - // lazy timeout is 3s and favicons are lazy added - do_timeout(3500, end_test); -} - -function end_test() { - var root = result.root; - root.containerOpen = false; - result.removeObserver(resultObserver); - - do_test_finished(); -} diff --git a/toolkit/components/places/tests/unit/test_doSetAndLoadFaviconForPage.js b/toolkit/components/places/tests/unit/test_doSetAndLoadFaviconForPage.js deleted file mode 100644 index 5aea9a0136f6..000000000000 --- a/toolkit/components/places/tests/unit/test_doSetAndLoadFaviconForPage.js +++ /dev/null @@ -1,206 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim:set ts=2 sw=2 sts=2 et: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Places unit test code. - * - * The Initial Developer of the Original Code is the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Gavin Sharp (original author) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Tests for nsIFaviconService::SetAndLoadFaviconForPage() - */ - -var iconsvc = PlacesUtils.favicons; - -function addBookmark(aURI) { - var bs = PlacesUtils.bookmarks; - return bs.insertBookmark(bs.unfiledBookmarksFolder, aURI, - bs.DEFAULT_INDEX, aURI.spec); -} - -function checkAddSucceeded(pageURI, mimetype, data) { - var savedFaviconURI = iconsvc.getFaviconForPage(pageURI); - var outMimeType = {}; - var outData = iconsvc.getFaviconData(savedFaviconURI, outMimeType, {}); - - // Ensure input and output are identical - do_check_eq(mimetype, outMimeType.value); - do_check_true(compareArrays(data, outData)); - do_check_guid_for_uri(pageURI); -} - -var favicons = [ - { - uri: uri(do_get_file("favicon-normal32.png")), - data: readFileData(do_get_file("favicon-normal32.png")), - mimetype: "image/png" - } -]; - -var tests = [ - { - desc: "test setAndLoadFaviconForPage for valid history uri", - pageURI: uri("http://test1.bar/"), - go: function go1() { - this.favicon = favicons[0]; - - iconsvc.setAndLoadFaviconForPage(this.pageURI, this.favicon.uri, true); - }, - check: function check1() { - checkAddSucceeded(this.pageURI, this.favicon.mimetype, this.favicon.data); - do_log_info("Check that the added page is marked as hidden."); - do_check_true(isUrlHidden(this.pageURI)); - do_log_info("Check that the added page has 0 frecency."); - do_check_eq(frecencyForUrl(this.pageURI), 0); - } - }, - - { - desc: "test setAndLoadFaviconForPage for bookmarked about: URIs", - pageURI: uri("about:test2"), - favicon: favicons[0], - go: function go3() { - // Add as bookmark - addBookmark(this.pageURI); - - iconsvc.setAndLoadFaviconForPage(this.pageURI, this.favicon.uri, true); - }, - check: function check3() { - checkAddSucceeded(this.pageURI, this.favicon.mimetype, this.favicon.data); - } - }, - - { - desc: "test setAndLoadFaviconForPage with history disabled for bookmarked URI", - pageURI: uri("http://test3.bar/"), - favicon: favicons[0], - go: function go5() { - // disable history - var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); - prefs.setBoolPref("places.history.enabled", false); - - // Add as bookmark - addBookmark(this.pageURI); - - iconsvc.setAndLoadFaviconForPage(this.pageURI, this.favicon.uri, true); - - prefs.setBoolPref("places.history.enabled", true); - }, - check: function check5() { - checkAddSucceeded(this.pageURI, this.favicon.mimetype, this.favicon.data); - } - }, - -]; - -if ("@mozilla.org/privatebrowsing;1" in Cc) { - tests.push({ - desc: "test setAndLoadFaviconForPage in PB mode for bookmarked URI", - pageURI: uri("http://test4.bar/"), - favicon: favicons[0], - go: function go6() { - try { - // enable PB - var pb = Cc["@mozilla.org/privatebrowsing;1"]. - getService(Ci.nsIPrivateBrowsingService); - var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); - prefs.setBoolPref("browser.privatebrowsing.keep_current_session", true); - pb.privateBrowsingEnabled = true; - - // Add as bookmark - addBookmark(this.pageURI); - - iconsvc.setAndLoadFaviconForPage(this.pageURI, this.favicon.uri, true); - - pb.privateBrowsingEnabled = false; - prefs.clearUserPref("browser.privatebrowsing.keep_current_session"); - } catch (ex) {do_throw("ex: " + ex); } - }, - check: function check6() { - checkAddSucceeded(this.pageURI, this.favicon.mimetype, this.favicon.data); - } - }); -} -var historyObserver = { - onBeginUpdateBatch: function() {}, - onEndUpdateBatch: function() {}, - onVisit: function() {}, - onTitleChanged: function() {}, - onBeforeDeleteURI: function() {}, - onDeleteURI: function() {}, - onClearHistory: function() {}, - onDeleteVisits: function() {}, - - onPageChanged: function historyObserver_onPageChanged(pageURI, what, value, guid) { - if (what != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) - return; - - do_check_guid_for_uri(pageURI, guid); - - if (pageURI.equals(tests[currentTestIndex].pageURI)) { - tests[currentTestIndex].check(); - currentTestIndex++; - if (currentTestIndex == tests.length) { - do_test_finished(); - } - else { - do_log_info(tests[currentTestIndex].desc); - tests[currentTestIndex].go(); - } - } - else - do_throw("Received PageChanged for a non-current test!"); - }, - - QueryInterface: function(iid) { - if (iid.equals(Ci.nsINavHistoryObserver) || - iid.equals(Ci.nsISupports)) { - return this; - } - throw Cr.NS_ERROR_NO_INTERFACE; - } -}; - -var currentTestIndex = 0; -function run_test() { - do_test_pending(); - - // check that the favicon loaded correctly - do_check_eq(favicons[0].data.length, 344); - - PlacesUtils.history.addObserver(historyObserver, false); - - // Start the tests - do_log_info(tests[currentTestIndex].desc); - tests[currentTestIndex].go(); -}; diff --git a/toolkit/components/places/tests/unit/test_doSetAndLoadFaviconForPage_failures.js b/toolkit/components/places/tests/unit/test_doSetAndLoadFaviconForPage_failures.js deleted file mode 100644 index 870d2e50b23c..000000000000 --- a/toolkit/components/places/tests/unit/test_doSetAndLoadFaviconForPage_failures.js +++ /dev/null @@ -1,212 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim:set ts=2 sw=2 sts=2 et: - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Places unit test code. - * - * The Initial Developer of the Original Code is the Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Marco Bonardo (Original Author) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * Tests failing cases of setAndLoadFaviconForPage - */ - -const PB_KEEP_SESSION_PREF = "browser.privatebrowsing.keep_current_session"; - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "pb", - "@mozilla.org/privatebrowsing;1", - "nsIPrivateBrowsingService"); - -let favicons = [ - { - uri: NetUtil.newURI(do_get_file("favicon-normal16.png")), - data: readFileData(do_get_file("favicon-normal16.png")), - mimetype: "image/png", - size: 286 - }, - { - uri: NetUtil.newURI(do_get_file("favicon-normal32.png")), - data: readFileData(do_get_file("favicon-normal32.png")), - mimetype: "image/png", - size: 344 - }, -]; - -let tests = [ - - { - desc: "test setAndLoadFaviconForPage for about: URIs", - pageURI: NetUtil.newURI("about:test1"), - go: function go1() { - - PlacesUtils.favicons.setAndLoadFaviconForPage(this.pageURI, favicons[0].uri, true); - }, - clean: function clean1() {} - }, - - { - desc: "test setAndLoadFaviconForPage with history disabled", - pageURI: NetUtil.newURI("http://test2.bar/"), - go: function go2() { - // Temporarily disable history. - Services.prefs.setBoolPref("places.history.enabled", false); - - PlacesUtils.favicons.setAndLoadFaviconForPage(this.pageURI, favicons[0].uri, true); - }, - clean: function clean2() { - Services.prefs.setBoolPref("places.history.enabled", true); - } - }, - - { - desc: "test setAndLoadFaviconForPage in PB mode for non-bookmarked URI", - pageURI: NetUtil.newURI("http://test3.bar/"), - go: function go3() { - if (!("@mozilla.org/privatebrowsing;1" in Cc)) - return; - - // Enable PB mode. - Services.prefs.setBoolPref(PB_KEEP_SESSION_PREF, true); - pb.privateBrowsingEnabled = true; - - PlacesUtils.favicons.setAndLoadFaviconForPage(this.pageURI, favicons[0].uri, true); - }, - clean: function clean3() { - if (!("@mozilla.org/privatebrowsing;1" in Cc)) - return; - - pb.privateBrowsingEnabled = false; - } - }, - - { - desc: "test setAndLoadFaviconForPage with error icon", - pageURI: NetUtil.newURI("http://test4.bar/"), - go: function go4() { - - PlacesUtils.favicons.setAndLoadFaviconForPage( - this.pageURI, NetUtil.newURI(FAVICON_ERRORPAGE_URL), true - ); - }, - clean: function clean4() {} - }, - - { // This is a valid icon set test, that will cause the closing notification. - desc: "test setAndLoadFaviconForPage for valid history uri", - pageURI: NetUtil.newURI("http://testfinal.bar/"), - go: function goFinal() { - PlacesUtils.favicons.setAndLoadFaviconForPage(this.pageURI, favicons[1].uri, true); - }, - clean: function cleanFinal() {} - }, - -]; - -let historyObserver = { - onBeginUpdateBatch: function() {}, - onEndUpdateBatch: function() {}, - onVisit: function() {}, - onTitleChanged: function() {}, - onBeforeDeleteURI: function() {}, - onDeleteURI: function() {}, - onClearHistory: function() {}, - onDeleteVisits: function() {}, - - onPageChanged: function historyObserver_onPageChanged(pageURI, what, value, guid) { - if (what != Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) - return; - - // dump tables, useful if the test fails. - //dump_table("moz_places"); - //dump_table("moz_favicons"); - - do_check_guid_for_uri(pageURI, guid); - - // Ensure we have been called by the last test. - do_check_true(pageURI.equals(NetUtil.newURI("http://testfinal.bar/"))); - - // Ensure there is only one entry in favicons table. - let stmt = DBConn().createStatement( - "SELECT url FROM moz_favicons" - ); - let c = 0; - try { - while (stmt.executeStep()) { - do_check_eq(stmt.row.url, favicons[1].uri.spec); - c++; - } - } - finally { - stmt.finalize(); - } - do_check_eq(c, 1); - - do_test_finished(); - }, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsINavHistoryObserver]) -}; - -let currentTest = null; - -function run_test() { - do_test_pending(); - - // check that the favicon loaded correctly - do_check_eq(favicons[0].data.length, favicons[0].size); - do_check_eq(favicons[1].data.length, favicons[1].size); - - // Observe history for onPageChanged notification. - PlacesUtils.history.addObserver(historyObserver, false); - - // We run all the tests, then we wait for an onPageChanged notification, - // ideally only the last test is successful, so it should be the only - // notification we get. Once we get it, test finishes. - runNextTest(); -}; - -function runNextTest() { - if (currentTest) { - currentTest.clean(); - } - - if (tests.length) { - currentTest = tests.shift(); - do_log_info(currentTest.desc); - currentTest.go(); - // Wait some time before calling the next test, this is needed to avoid - // invoking clean() too early. The first async step should run at least. - do_timeout(500, runNextTest); - } -} diff --git a/toolkit/components/places/tests/unit/test_faviconService_expireAllFavicons.js b/toolkit/components/places/tests/unit/test_faviconService_expireAllFavicons.js deleted file mode 100644 index 71f02dc834ea..000000000000 --- a/toolkit/components/places/tests/unit/test_faviconService_expireAllFavicons.js +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: sw=2 ts=2 sts=2 expandtab - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Marco Bonardo (Original Author) - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * This test ensures favicons are correctly expired by expireAllFavicons API, - * also when cache is cleared. - */ - -const TEST_URI = "http://test.com/"; -const TEST_ICON_URI = "http://test.com/favicon.ico"; - -const TEST_BOOKMARK_URI = "http://bookmarked.test.com/"; -const TEST_BOOKMARK_ICON_URI = "http://bookmarked.test.com/favicon.ico"; - -const TOPIC_ICONS_EXPIRATION_FINISHED = "places-favicons-expired"; - -add_test(function() { - do_log_info("Test that expireAllFavicons works as expected."); - - let bmURI = NetUtil.newURI(TEST_BOOKMARK_URI); - let vsURI = NetUtil.newURI(TEST_URI); - - Services.obs.addObserver(function(aSubject, aTopic, aData) { - Services.obs.removeObserver(arguments.callee, aTopic); - - // Check visited page does not have an icon - try { - PlacesUtils.favicons.getFaviconForPage(vsURI); - do_throw("Visited page has still a favicon!"); - } catch (ex) { /* page should not have a favicon */ } - - // Check bookmarked page does not have an icon - try { - PlacesUtils.favicons.getFaviconForPage(bmURI); - do_throw("Bookmarked page has still a favicon!"); - } catch (ex) { /* page should not have a favicon */ } - - run_next_test(); - }, TOPIC_ICONS_EXPIRATION_FINISHED, false); - - // Add a page with a bookmark. - PlacesUtils.bookmarks.insertBookmark( - PlacesUtils.toolbarFolderId, bmURI, - PlacesUtils.bookmarks.DEFAULT_INDEX, "Test bookmark" - ); - - // Set a favicon for the page. - PlacesUtils.favicons.setFaviconUrlForPage( - bmURI, NetUtil.newURI(TEST_BOOKMARK_ICON_URI) - ); - do_check_eq(PlacesUtils.favicons.getFaviconForPage(bmURI).spec, - TEST_BOOKMARK_ICON_URI); - - // Add a visited page. - let visitId = PlacesUtils.history.addVisit( - vsURI, Date.now() * 1000, null, - PlacesUtils.history.TRANSITION_TYPED, false, 0 - ); - - // Set a favicon for the page. - PlacesUtils.favicons - .setFaviconUrlForPage(vsURI, NetUtil.newURI(TEST_ICON_URI)); - do_check_eq(PlacesUtils.favicons.getFaviconForPage(vsURI).spec, - TEST_ICON_URI); - - PlacesUtils.favicons.expireAllFavicons(); -}); - -function run_test() { - run_next_test(); -} diff --git a/toolkit/components/places/tests/unit/test_history_observer.js b/toolkit/components/places/tests/unit/test_history_observer.js index 6f79e97f34f2..d868c5d3b6ba 100644 --- a/toolkit/components/places/tests/unit/test_history_observer.js +++ b/toolkit/components/places/tests/unit/test_history_observer.js @@ -131,7 +131,7 @@ add_test(function test_onPageChanged() { onNotify(function onPageChanged(aURI, aChangedAttribute, aNewValue, aGUID) { do_check_eq(aChangedAttribute, Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON); do_check_true(aURI.equals(testuri)); - do_check_eq(aNewValue, iconurl); + do_check_eq(aNewValue, SMALLPNG_DATA_URI.spec); do_check_guid_for_uri(aURI, aGUID); run_next_test(); @@ -139,11 +139,9 @@ add_test(function test_onPageChanged() { let [testuri] = add_visit(); - let iconurl = "file:///favicon-normal32.png"; - let data = readFileData(do_get_file("favicon-normal32.png")); - PlacesUtils.favicons.setFaviconData(NetUtil.newURI(iconurl), - data, data.length, "image/png", - Number.MAX_VALUE); - - PlacesUtils.favicons.setFaviconUrlForPage(testuri, NetUtil.newURI(iconurl)); + // The new favicon for the page must have data associated with it in order to + // receive the onPageChanged notification. To keep this test self-contained, + // we use an URI representing the smallest possible PNG file. + PlacesUtils.favicons.setAndFetchFaviconForPage(testuri, SMALLPNG_DATA_URI, + false, null); }); diff --git a/toolkit/components/places/tests/unit/test_preventive_maintenance.js b/toolkit/components/places/tests/unit/test_preventive_maintenance.js index 04c42663a5f4..9a238456b340 100644 --- a/toolkit/components/places/tests/unit/test_preventive_maintenance.js +++ b/toolkit/components/places/tests/unit/test_preventive_maintenance.js @@ -1172,14 +1172,13 @@ tests.push({ bs.DEFAULT_INDEX); do_check_true(this._separatorId > 0); ts.tagURI(this._uri1, ["testtag"]); - fs.setFaviconUrlForPage(this._uri2, - uri("http://www2.mozilla.org/favicon.ico")); + fs.setAndFetchFaviconForPage(this._uri2, SMALLPNG_DATA_URI, false); bs.setKeywordForBookmark(this._bookmarkId, "testkeyword"); as.setPageAnnotation(this._uri2, "anno", "anno", 0, as.EXPIRE_NEVER); as.setItemAnnotation(this._bookmarkId, "anno", "anno", 0, as.EXPIRE_NEVER); }, - check: function() { + asyncCheck: function (aCallback) { // Check that all items are correct do_check_true(bh.isVisited(this._uri1)); do_check_true(bh.isVisited(this._uri2)); @@ -1192,10 +1191,14 @@ tests.push({ do_check_eq(ts.getTagsForURI(this._uri1).length, 1); do_check_eq(bs.getKeywordForBookmark(this._bookmarkId), "testkeyword"); - do_check_eq(fs.getFaviconForPage(this._uri2).spec, - "http://www2.mozilla.org/favicon.ico"); do_check_eq(as.getPageAnnotation(this._uri2, "anno"), "anno"); do_check_eq(as.getItemAnnotation(this._bookmarkId, "anno"), "anno"); + + fs.getFaviconURLForPage(this._uri2, + function AC_onFaviconDataAvailable(aURI) { + do_check_true(aURI.equals(SMALLPNG_DATA_URI)); + aCallback(); + }); } }); @@ -1207,26 +1210,37 @@ let observer = { // Check the lastMaintenance time has been saved. do_check_neq(Services.prefs.getIntPref("places.database.lastMaintenance"), null); - try {current_test.check();} - catch (ex){ do_throw(ex);} + function afterCheck() { + cleanDatabase(); - cleanDatabase(); - - if (tests.length) { - current_test = tests.shift(); - dump("\nExecuting test: " + current_test.name + "\n" + "*** " + current_test.desc + "\n"); - current_test.setup(); - PlacesDBUtils.maintenanceOnIdle(); + if (tests.length) { + current_test = tests.shift(); + do_log_info("Executing test: " + current_test.name + " *** " + current_test.desc); + current_test.setup(); + PlacesDBUtils.maintenanceOnIdle(); + } + else { + Services.obs.removeObserver(observer, + FINISHED_MAINTENANCE_NOTIFICATION_TOPIC); + // Sanity check: all roots should be intact + do_check_eq(bs.getFolderIdForItem(bs.placesRoot), 0); + do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot); + do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot); + do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot); + do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot); + do_test_finished(); + } } - else { - Services.obs.removeObserver(this, FINISHED_MAINTENANCE_NOTIFICATION_TOPIC); - // Sanity check: all roots should be intact - do_check_eq(bs.getFolderIdForItem(bs.placesRoot), 0); - do_check_eq(bs.getFolderIdForItem(bs.bookmarksMenuFolder), bs.placesRoot); - do_check_eq(bs.getFolderIdForItem(bs.tagsFolder), bs.placesRoot); - do_check_eq(bs.getFolderIdForItem(bs.unfiledBookmarksFolder), bs.placesRoot); - do_check_eq(bs.getFolderIdForItem(bs.toolbarFolder), bs.placesRoot); - do_test_finished(); + + try { + if (current_test.asyncCheck) { + current_test.asyncCheck(afterCheck); + } else { + current_test.check(); + afterCheck(); + } + } catch (ex) { + do_throw(ex); } } } diff --git a/toolkit/components/places/tests/unit/xpcshell.ini b/toolkit/components/places/tests/unit/xpcshell.ini index 62dddd89add3..1fb05f75418d 100644 --- a/toolkit/components/places/tests/unit/xpcshell.ini +++ b/toolkit/components/places/tests/unit/xpcshell.ini @@ -18,7 +18,6 @@ fail-if = os == "android" fail-if = os == "android" [test_399606.js] [test_402799.js] -[test_404630.js] [test_405497.js] [test_408221.js] [test_412132.js] @@ -36,7 +35,6 @@ skip-if = os == "android" [test_429505_remove_shortcuts.js] [test_433317_query_title_update.js] [test_433525_hasChildren_crash.js] -[test_451499.js] [test_452777.js] [test_454977.js] [test_463863.js] @@ -62,19 +60,9 @@ skip-if = os == "android" [test_childlessTags.js] [test_crash_476292.js] [test_database_replaceOnStartup.js] -[test_doReplaceFaviconData.js] -[test_doReplaceFaviconDataFromDataURL.js] -[test_doSetAndLoadFaviconForPage.js] -[test_doSetAndLoadFaviconForPage_failures.js] -# Bug 676989: test fails consistently on Android -fail-if = os == "android" [test_download_history.js] # Bug 676989: test fails consistently on Android fail-if = os == "android" -[test_faviconService_expireAllFavicons.js] -[test_favicons.js] -# Bug 676989: test fails consistently on Android -fail-if = os == "android" [test_frecency.js] # Bug 676989: test hangs consistently on Android skip-if = os == "android" @@ -94,7 +82,6 @@ skip-if = os == "android" [test_lastModified.js] [test_markpageas.js] [test_mozIAsyncLivemarks.js] -[test_moz-anno_favicon_mime_type.js] [test_multi_queries.js] # Bug 676989: test fails consistently on Android fail-if = os == "android"