michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /** michael@0: * This file tests setAndFetchFaviconForPage when it is called with invalid michael@0: * arguments, and when no favicon is stored for the given arguments. michael@0: */ michael@0: function test() { michael@0: // Initialization michael@0: waitForExplicitFinish(); michael@0: let windowsToClose = []; michael@0: let favIcon16Location = michael@0: "http://example.org/tests/toolkit/components/places/tests/browser/favicon-normal16.png"; michael@0: let favIcon32Location = michael@0: "http://example.org/tests/toolkit/components/places/tests/browser/favicon-normal32.png"; michael@0: let favIcon16URI = NetUtil.newURI(favIcon16Location); michael@0: let favIcon32URI = NetUtil.newURI(favIcon32Location); michael@0: let lastPageURI = NetUtil.newURI("http://example.com/verification"); michael@0: // This error icon must stay in sync with FAVICON_ERRORPAGE_URL in michael@0: // nsIFaviconService.idl, aboutCertError.xhtml and netError.xhtml. michael@0: let favIconErrorPageURI = michael@0: NetUtil.newURI("chrome://global/skin/icons/warning-16.png"); michael@0: let favIconsResultCount = 0; michael@0: let pageURI; michael@0: michael@0: function testOnWindow(aOptions, aCallback) { michael@0: whenNewWindowLoaded(aOptions, function(aWin) { michael@0: windowsToClose.push(aWin); michael@0: executeSoon(function() aCallback(aWin)); michael@0: }); michael@0: }; michael@0: michael@0: // This function is called after calling finish() on the test. michael@0: registerCleanupFunction(function() { michael@0: windowsToClose.forEach(function(aWin) { michael@0: aWin.close(); michael@0: }); michael@0: }); michael@0: michael@0: function checkFavIconsDBCount(aCallback) { michael@0: let stmt = DBConn().createAsyncStatement("SELECT url FROM moz_favicons"); michael@0: stmt.executeAsync({ michael@0: handleResult: function final_handleResult(aResultSet) { michael@0: for (let row; (row = aResultSet.getNextRow()); ) { michael@0: favIconsResultCount++; michael@0: } michael@0: }, michael@0: handleError: function final_handleError(aError) { michael@0: throw("Unexpected error (" + aError.result + "): " + aError.message); michael@0: }, michael@0: handleCompletion: function final_handleCompletion(aReason) { michael@0: //begin testing michael@0: info("Previous records in moz_favicons: " + favIconsResultCount); michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: } michael@0: }); michael@0: stmt.finalize(); michael@0: } michael@0: michael@0: function testNullPageURI(aWindow, aCallback) { michael@0: try { michael@0: aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(null, favIcon16URI, michael@0: true, aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); michael@0: throw("Exception expected because aPageURI is null."); michael@0: } catch (ex) { michael@0: // We expected an exception. michael@0: ok(true, "Exception expected because aPageURI is null"); michael@0: } michael@0: michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: } michael@0: michael@0: function testNullFavIconURI(aWindow, aCallback) { michael@0: try { michael@0: aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage( michael@0: NetUtil.newURI("http://example.com/null_faviconURI"), null, true, michael@0: aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); michael@0: throw("Exception expected because aFaviconURI is null."); michael@0: } catch (ex) { michael@0: // We expected an exception. michael@0: ok(true, "Exception expected because aFaviconURI is null."); michael@0: } michael@0: michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: } michael@0: michael@0: function testAboutURI(aWindow, aCallback) { michael@0: aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage( michael@0: NetUtil.newURI("about:testAboutURI"), favIcon16URI, true, michael@0: aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); michael@0: michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: } michael@0: michael@0: function testPrivateBrowsingNonBookmarkedURI(aWindow, aCallback) { michael@0: let pageURI = NetUtil.newURI("http://example.com/privateBrowsing"); michael@0: addVisits({ uri: pageURI, transitionType: TRANSITION_TYPED }, aWindow, michael@0: function () { michael@0: aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, michael@0: favIcon16URI, true, aWindow.PlacesUtils.favicons.FAVICON_LOAD_PRIVATE); michael@0: michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: }); michael@0: } michael@0: michael@0: function testDisabledHistory(aWindow, aCallback) { michael@0: let pageURI = NetUtil.newURI("http://example.com/disabledHistory"); michael@0: addVisits({ uri: pageURI, transition: TRANSITION_TYPED }, aWindow, michael@0: function () { michael@0: aWindow.Services.prefs.setBoolPref("places.history.enabled", false); michael@0: michael@0: aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, michael@0: favIcon16URI, true, michael@0: aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); michael@0: michael@0: // The setAndFetchFaviconForPage function calls CanAddURI synchronously, thus michael@0: // we can set the preference back to true immediately . We don't clear the michael@0: // preference because not all products enable Places by default. michael@0: aWindow.Services.prefs.setBoolPref("places.history.enabled", true); michael@0: michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: }); michael@0: } michael@0: michael@0: function testErrorIcon(aWindow, aCallback) { michael@0: let pageURI = NetUtil.newURI("http://example.com/errorIcon"); michael@0: let places = [{ uri: pageURI, transition: TRANSITION_TYPED }]; michael@0: addVisits({ uri: pageURI, transition: TRANSITION_TYPED }, aWindow, michael@0: function () { michael@0: aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(pageURI, michael@0: favIconErrorPageURI, true, michael@0: aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); michael@0: michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: }); michael@0: } michael@0: michael@0: function testNonExistingPage(aWindow, aCallback) { michael@0: aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage( michael@0: NetUtil.newURI("http://example.com/nonexistingPage"), favIcon16URI, true, michael@0: aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); michael@0: michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: } michael@0: michael@0: function testFinalVerification(aWindow, aCallback) { michael@0: // Only the last test should raise the onPageChanged notification, michael@0: // executing the waitForFaviconChanged callback. michael@0: waitForFaviconChanged(lastPageURI, favIcon32URI, aWindow, michael@0: function final_callback() { michael@0: // Check that only one record corresponding to the last favicon is present. michael@0: let resultCount = 0; michael@0: let stmt = DBConn().createAsyncStatement("SELECT url FROM moz_favicons"); michael@0: stmt.executeAsync({ michael@0: handleResult: function final_handleResult(aResultSet) { michael@0: michael@0: // If the moz_favicons DB had been previously loaded (before our michael@0: // test began), we should focus only in the URI we are testing and michael@0: // skip the URIs not related to our test. michael@0: if (favIconsResultCount > 0) { michael@0: for (let row; (row = aResultSet.getNextRow()); ) { michael@0: if (favIcon32URI.spec === row.getResultByIndex(0)) { michael@0: is(favIcon32URI.spec, row.getResultByIndex(0), michael@0: "Check equal favicons"); michael@0: resultCount++; michael@0: } michael@0: } michael@0: } else { michael@0: for (let row; (row = aResultSet.getNextRow()); ) { michael@0: is(favIcon32URI.spec, row.getResultByIndex(0), michael@0: "Check equal favicons"); michael@0: resultCount++; michael@0: } michael@0: } michael@0: }, michael@0: handleError: function final_handleError(aError) { michael@0: throw("Unexpected error (" + aError.result + "): " + aError.message); michael@0: }, michael@0: handleCompletion: function final_handleCompletion(aReason) { michael@0: is(Ci.mozIStorageStatementCallback.REASON_FINISHED, aReason, michael@0: "Check reasons are equal"); michael@0: is(1, resultCount, "Check result count"); michael@0: if (aCallback) { michael@0: aCallback(); michael@0: } michael@0: } michael@0: }); michael@0: stmt.finalize(); michael@0: }); michael@0: michael@0: // This is the only test that should cause the waitForFaviconChanged michael@0: // callback to be invoked. In turn, the callback will invoke michael@0: // finish() causing the tests to finish. michael@0: addVisits({ uri: lastPageURI, transition: TRANSITION_TYPED }, aWindow, michael@0: function () { michael@0: aWindow.PlacesUtils.favicons.setAndFetchFaviconForPage(lastPageURI, michael@0: favIcon32URI, true, michael@0: aWindow.PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE); michael@0: }); michael@0: } michael@0: michael@0: checkFavIconsDBCount(function () { michael@0: testOnWindow({}, function(aWin) { michael@0: testNullPageURI(aWin, function () { michael@0: testOnWindow({}, function(aWin) { michael@0: testNullFavIconURI(aWin, function() { michael@0: testOnWindow({}, function(aWin) { michael@0: testAboutURI(aWin, function() { michael@0: testOnWindow({private: true}, function(aWin) { michael@0: testPrivateBrowsingNonBookmarkedURI(aWin, function () { michael@0: testOnWindow({}, function(aWin) { michael@0: testDisabledHistory(aWin, function () { michael@0: testOnWindow({}, function(aWin) { michael@0: testErrorIcon(aWin, function() { michael@0: testOnWindow({}, function(aWin) { michael@0: testNonExistingPage(aWin, function() { michael@0: testOnWindow({}, function(aWin) { michael@0: testFinalVerification(aWin, function() { michael@0: finish(); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }); michael@0: }