summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/tests
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/places/tests')
-rw-r--r--toolkit/components/places/tests/PlacesTestUtils.sys.mjs37
-rw-r--r--toolkit/components/places/tests/browser/browser.toml12
-rw-r--r--toolkit/components/places/tests/browser/browser_visituri_restriction.js227
-rw-r--r--toolkit/components/places/tests/browser/browser_visituri_restriction_origin.js92
-rw-r--r--toolkit/components/places/tests/browser/head.js77
-rw-r--r--toolkit/components/places/tests/chrome/test_cached_favicon.xhtml15
-rw-r--r--toolkit/components/places/tests/expiration/test_debug_expiration.js16
-rw-r--r--toolkit/components/places/tests/favicons/head_favicons.js87
-rw-r--r--toolkit/components/places/tests/favicons/test_cached-favicon_mime_type.js20
-rw-r--r--toolkit/components/places/tests/favicons/test_expire_on_new_icons.js38
-rw-r--r--toolkit/components/places/tests/favicons/test_favicons_conversions.js37
-rw-r--r--toolkit/components/places/tests/favicons/test_favicons_protocols_ref.js17
-rw-r--r--toolkit/components/places/tests/favicons/test_getFaviconDataForPage.js16
-rw-r--r--toolkit/components/places/tests/favicons/test_getFaviconURLForPage.js16
-rw-r--r--toolkit/components/places/tests/favicons/test_heavy_favicon.js4
-rw-r--r--toolkit/components/places/tests/favicons/test_incremental_vacuum.js7
-rw-r--r--toolkit/components/places/tests/favicons/test_multiple_frames.js12
-rw-r--r--toolkit/components/places/tests/favicons/test_page-icon_protocol.js44
-rw-r--r--toolkit/components/places/tests/favicons/test_replaceFaviconData.js395
-rw-r--r--toolkit/components/places/tests/favicons/test_replaceFaviconDataFromDataURL.js537
-rw-r--r--toolkit/components/places/tests/favicons/test_root_icons.js67
-rw-r--r--toolkit/components/places/tests/favicons/test_setFaviconForPage.js245
-rw-r--r--toolkit/components/places/tests/favicons/xpcshell.toml6
-rw-r--r--toolkit/components/places/tests/gtest/places_test_harness_tail.h8
-rw-r--r--toolkit/components/places/tests/head_common.js37
-rw-r--r--toolkit/components/places/tests/history/test_remove.js15
-rw-r--r--toolkit/components/places/tests/unit/test_PlacesQuery_history.js33
27 files changed, 962 insertions, 1155 deletions
diff --git a/toolkit/components/places/tests/PlacesTestUtils.sys.mjs b/toolkit/components/places/tests/PlacesTestUtils.sys.mjs
index 4e459d2e32..97dda6367f 100644
--- a/toolkit/components/places/tests/PlacesTestUtils.sys.mjs
+++ b/toolkit/components/places/tests/PlacesTestUtils.sys.mjs
@@ -156,6 +156,43 @@ export var PlacesTestUtils = Object.freeze({
await Promise.all(faviconPromises);
},
+ /*
+ * Helper function to call PlacesUtils.favicons.setFaviconForPage() and waits
+ * finishing setting. This function throws an error if the status of
+ * PlacesUtils.favicons.setFaviconForPage() is not success.
+ *
+ * @param {string or nsIURI} pageURI
+ * @param {string or nsIURI} faviconURI
+ * @param {string or nsIURI} faviconDataURL
+ * @param {Number} [optional] expiration
+ * @return {Promise} waits for finishing setting
+ */
+ setFaviconForPage(pageURI, faviconURI, faviconDataURL, expiration = 0) {
+ return new Promise((resolve, reject) => {
+ lazy.PlacesUtils.favicons.setFaviconForPage(
+ pageURI instanceof Ci.nsIURI ? pageURI : Services.io.newURI(pageURI),
+ faviconURI instanceof Ci.nsIURI
+ ? faviconURI
+ : Services.io.newURI(faviconURI),
+ faviconDataURL instanceof Ci.nsIURI
+ ? faviconDataURL
+ : Services.io.newURI(faviconDataURL),
+ expiration,
+ status => {
+ if (Components.isSuccessCode(status)) {
+ resolve(status);
+ } else {
+ reject(
+ new Error(
+ `Failed to process setFaviconForPage(): status code = ${status}`
+ )
+ );
+ }
+ }
+ );
+ });
+ },
+
/**
* Clears any favicons stored in the database.
*/
diff --git a/toolkit/components/places/tests/browser/browser.toml b/toolkit/components/places/tests/browser/browser.toml
index b7d688c980..aceee48f24 100644
--- a/toolkit/components/places/tests/browser/browser.toml
+++ b/toolkit/components/places/tests/browser/browser.toml
@@ -117,3 +117,15 @@ support-files = [
"favicon.html",
"final.html",
]
+
+["browser_visituri_restriction.js"]
+skip-if = [
+ "verify",
+ "os == 'linux' && (asan || tsan)", # Bug 1891145
+]
+
+["browser_visituri_restriction_origin.js"]
+skip-if = [
+ "verify",
+ "os == 'linux' && (asan || tsan)", # Bug 1891145
+]
diff --git a/toolkit/components/places/tests/browser/browser_visituri_restriction.js b/toolkit/components/places/tests/browser/browser_visituri_restriction.js
new file mode 100644
index 0000000000..2af41e6f51
--- /dev/null
+++ b/toolkit/components/places/tests/browser/browser_visituri_restriction.js
@@ -0,0 +1,227 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+"use strict";
+
+const TEST_PAGE = `data:text/html,
+ <a href="https://example.com/" target="_blank">https://example.com</a>
+ <a href="http://example.com/" target="_blank">http://example.com</a>
+ <a href="https://www.example.com/" target="_blank">https://www.example.com</a>
+ <a href="https://example.org/" target="_blank">https://example.org</a>`;
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ // Enable restriction feature.
+ ["places.history.floodingPrevention.enabled", true],
+ // Restrict from the second visit.
+ ["places.history.floodingPrevention.restrictionCount", 1],
+ ["places.history.floodingPrevention.restrictionExpireSeconds", 4],
+ // Not apply flooding prevention until some seconds elapse after user
+ // interaction begins.
+ [
+ "places.history.floodingPrevention.maxSecondsFromLastUserInteraction",
+ 4,
+ ],
+ // To enable UserActivation by EventUtils.synthesizeMouseAtCenter() in
+ // ContentTask.spawn() in synthesizeVisitByUser().
+ ["test.events.async.enabled", true],
+ ],
+ });
+ await clearHistoryAndHistoryCache();
+});
+
+add_task(async function basic() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: TEST_PAGE },
+ async browser => {
+ info("Sanity check");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ await assertLinkVisitedStatus(browser, "https://www.example.com/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ await assertLinkVisitedStatus(browser, "https://example.org/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+
+ info("Visit https://example.com/ by user");
+ await synthesizeVisitByUser(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 1,
+ isVisited: true,
+ });
+
+ info(
+ "Visit https://example.com/ by script within maxSecondsFromLastUserInteraction"
+ );
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 3,
+ isVisited: true,
+ });
+
+ await waitForPrefSeconds("maxSecondsFromLastUserInteraction");
+
+ info(
+ "Visit https://example.com/ by script without maxSecondsFromLastUserInteraction"
+ );
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 4,
+ isVisited: true,
+ });
+
+ info("Visit again, but it should be restricted");
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 4,
+ isVisited: true,
+ });
+
+ info("Check other");
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ await assertLinkVisitedStatus(browser, "http://example.com/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ await assertLinkVisitedStatus(browser, "https://www.example.com/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ await assertLinkVisitedStatus(browser, "https://example.org/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ }
+ );
+
+ await clearHistoryAndHistoryCache();
+});
+
+add_task(async function expireRestriction() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: TEST_PAGE },
+ async browser => {
+ info("Visit https://example.com/ by user");
+ await synthesizeVisitByUser(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 1,
+ isVisited: true,
+ });
+
+ info(
+ "Visit https://example.com/ by script within maxSecondsFromLastUserInteraction"
+ );
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 3,
+ isVisited: true,
+ });
+
+ await waitForPrefSeconds("maxSecondsFromLastUserInteraction");
+
+ info(
+ "Visit https://example.com/ by script without maxSecondsFromLastUserInteraction"
+ );
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 4,
+ isVisited: true,
+ });
+
+ await waitForPrefSeconds("restrictionExpireSeconds");
+
+ info("Visit again, it should not be restricted");
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 5,
+ isVisited: true,
+ });
+ }
+ );
+
+ await clearHistoryAndHistoryCache();
+});
+
+add_task(async function userInputAlwaysAcceptable() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: TEST_PAGE },
+ async browser => {
+ info("Visit by user");
+ await synthesizeVisitByUser(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 1,
+ isVisited: true,
+ });
+ await synthesizeVisitByUser(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 2,
+ isVisited: true,
+ });
+
+ await waitForPrefSeconds("maxSecondsFromLastUserInteraction");
+
+ info("Visit by user input");
+ await synthesizeVisitByUser(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 3,
+ isVisited: true,
+ });
+ await synthesizeVisitByUser(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 4,
+ isVisited: true,
+ });
+ }
+ );
+
+ await clearHistoryAndHistoryCache();
+});
+
+add_task(async function disable() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["places.history.floodingPrevention.enabled", false]],
+ });
+
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: TEST_PAGE },
+ async browser => {
+ info("Any visits are stored");
+ for (let i = 0; i < 3; i++) {
+ await synthesizeVisitByScript(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: i + 1,
+ isVisited: true,
+ });
+ }
+ }
+ );
+
+ await clearHistoryAndHistoryCache();
+});
+
+async function waitForPrefSeconds(pref) {
+ info(`Wait until elapsing ${pref}`);
+ return new Promise(r =>
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ setTimeout(
+ r,
+ Services.prefs.getIntPref(`places.history.floodingPrevention.${pref}`) *
+ 1000 +
+ 100
+ )
+ );
+}
diff --git a/toolkit/components/places/tests/browser/browser_visituri_restriction_origin.js b/toolkit/components/places/tests/browser/browser_visituri_restriction_origin.js
new file mode 100644
index 0000000000..ee691c79e8
--- /dev/null
+++ b/toolkit/components/places/tests/browser/browser_visituri_restriction_origin.js
@@ -0,0 +1,92 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+"use strict";
+
+const TEST_PAGE = `data:text/html,
+ <a href="https://example.com/" target="_blank">https://example.com</a>
+ <a href="http://example.com/" target="_blank">http://example.com</a>
+ <a href="https://www.example.com/" target="_blank">https://www.example.com</a>
+ <a href="https://example.org/" target="_blank">https://example.org</a>`;
+
+add_setup(async function () {
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ // Enable restriction feature.
+ ["places.history.floodingPrevention.enabled", true],
+ // Restrict from the second visit.
+ ["places.history.floodingPrevention.restrictionCount", 1],
+ // Stop expiring.
+ ["places.history.floodingPrevention.restrictionExpireSeconds", 100],
+ // Always appply flooding preveition.
+ [
+ "places.history.floodingPrevention.maxSecondsFromLastUserInteraction",
+ 0,
+ ],
+ // To enable UserActivation by EventUtils.synthesizeMouseAtCenter() in ContentTask.spawn() in synthesizeVisitByUser().
+ ["test.events.async.enabled", true],
+ ],
+ });
+});
+
+add_task(async function same_origin_but_other() {
+ await BrowserTestUtils.withNewTab(
+ { gBrowser, url: TEST_PAGE },
+ async browser => {
+ info("Sanity check");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ await assertLinkVisitedStatus(browser, "http://example.com/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ await assertLinkVisitedStatus(browser, "https://www.example.com/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+ await assertLinkVisitedStatus(browser, "https://example.org/", {
+ visitCount: 0,
+ isVisited: false,
+ });
+
+ info("Visit https://example.com/ by user");
+ await synthesizeVisitByUser(browser, "https://example.com/");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 1,
+ isVisited: true,
+ });
+
+ info("Visit others by Scripts");
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ await synthesizeVisitByScript(browser, "http://example.com/");
+ await synthesizeVisitByScript(browser, "https://www.example.com/");
+ await synthesizeVisitByScript(browser, "https://example.org/");
+
+ info("Check the status");
+ await assertLinkVisitedStatus(browser, "https://example.com/", {
+ visitCount: 1,
+ isVisited: true,
+ });
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ await assertLinkVisitedStatus(browser, "http://example.com/", {
+ visitCount: 0,
+ isVisited: true,
+ });
+ await assertLinkVisitedStatus(browser, "https://www.example.com/", {
+ visitCount: 0,
+ isVisited: true,
+ });
+ await assertLinkVisitedStatus(browser, "https://example.org/", {
+ visitCount: 1,
+ isVisited: true,
+ });
+ }
+ );
+
+ await clearHistoryAndHistoryCache();
+});
diff --git a/toolkit/components/places/tests/browser/head.js b/toolkit/components/places/tests/browser/head.js
index b1b916ee29..da40a832c6 100644
--- a/toolkit/components/places/tests/browser/head.js
+++ b/toolkit/components/places/tests/browser/head.js
@@ -17,3 +17,80 @@ function whenNewWindowLoaded(aOptions, aCallback) {
BrowserTestUtils.waitForNewWindow().then(aCallback);
OpenBrowserWindow(aOptions);
}
+
+async function clearHistoryAndHistoryCache() {
+ await PlacesUtils.history.clear();
+ // Clear HistoryRestiction cache as well.
+ Cc["@mozilla.org/browser/history;1"]
+ .getService(Ci.mozIAsyncHistory)
+ .clearCache();
+}
+
+async function synthesizeVisitByUser(browser, url) {
+ let onNewTab = BrowserTestUtils.waitForNewTab(browser.ownerGlobal.gBrowser);
+ // We intentionally turn off this a11y check, because the following click is
+ // purposefully sent on an arbitrary web content that is not expected to be
+ // tested by itself with the browser mochitests, therefore this rule check
+ // shall be ignored by a11y_checks suite.
+ AccessibilityUtils.setEnv({ mustHaveAccessibleRule: false });
+ await ContentTask.spawn(browser, [url], async ([href]) => {
+ EventUtils.synthesizeMouseAtCenter(
+ content.document.querySelector(`a[href='${href}'`),
+ {},
+ content
+ );
+ });
+ AccessibilityUtils.resetEnv();
+ let tab = await onNewTab;
+ BrowserTestUtils.removeTab(tab);
+}
+
+async function synthesizeVisitByScript(browser, url) {
+ let onNewTab = BrowserTestUtils.waitForNewTab(browser.ownerGlobal.gBrowser);
+ AccessibilityUtils.setEnv({ mustHaveAccessibleRule: false });
+ await ContentTask.spawn(browser, [url], async ([href]) => {
+ let a = content.document.querySelector(`a[href='${href}'`);
+ a.click();
+ });
+ AccessibilityUtils.resetEnv();
+ let tab = await onNewTab;
+ BrowserTestUtils.removeTab(tab);
+}
+
+async function assertLinkVisitedStatus(
+ browser,
+ url,
+ { visitCount: expectedVisitCount, isVisited: expectedVisited }
+) {
+ await BrowserTestUtils.waitForCondition(async () => {
+ let visitCount =
+ (await PlacesTestUtils.getDatabaseValue("moz_places", "visit_count", {
+ url,
+ })) ?? 0;
+
+ if (visitCount != expectedVisitCount) {
+ return false;
+ }
+
+ Assert.equal(visitCount, expectedVisitCount, "The visit count is correct");
+ return true;
+ });
+
+ await ContentTask.spawn(
+ browser,
+ [url, expectedVisited],
+ async ([href, visited]) => {
+ // ElementState::VISITED
+ const VISITED_STATE = 1 << 18;
+ await ContentTaskUtils.waitForCondition(() => {
+ let isVisited = !!(
+ content.InspectorUtils.getContentState(
+ content.document.querySelector(`a[href='${href}']`)
+ ) & VISITED_STATE
+ );
+ return isVisited == visited;
+ });
+ }
+ );
+ Assert.ok(true, "The visited state is corerct");
+}
diff --git a/toolkit/components/places/tests/chrome/test_cached_favicon.xhtml b/toolkit/components/places/tests/chrome/test_cached_favicon.xhtml
index f7e7f4f1d8..1046574bdf 100644
--- a/toolkit/components/places/tests/chrome/test_cached_favicon.xhtml
+++ b/toolkit/components/places/tests/chrome/test_cached_favicon.xhtml
@@ -104,19 +104,12 @@ function test()
// icon with a page explicitly in order for it to be visible through
// the protocol.
info("Replace favicon data");
- var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
- .createInstance(Ci.nsIPrincipal);
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
- Services.io.newURI(tests[1].url),
- tests[1].expectedIcon,
- (Date.now() + 86400) * 1000,
- systemPrincipal);
- info("Set favicon data");
- PlacesUtils.favicons.setAndFetchFaviconForPage(
+ PlacesUtils.favicons.setFaviconForPage(
Services.io.newURI("https://example.com/favicon_annotations"),
Services.io.newURI(tests[1].url),
- true, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, null,
- systemPrincipal);
+ Services.io.newURI(tests[1].expectedIcon),
+ (Date.now() + 86400) * 1000,
+ );
// And start our test process.
loadNextTest();
diff --git a/toolkit/components/places/tests/expiration/test_debug_expiration.js b/toolkit/components/places/tests/expiration/test_debug_expiration.js
index 204295d46c..22657e6b24 100644
--- a/toolkit/components/places/tests/expiration/test_debug_expiration.js
+++ b/toolkit/components/places/tests/expiration/test_debug_expiration.js
@@ -356,13 +356,7 @@ add_task(async function test_expire_icons() {
}
if (entry.icon) {
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
- Services.io.newURI(entry.icon),
- dataUrl,
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- await PlacesTestUtils.addFavicons(new Map([[entry.page, entry.icon]]));
+ await PlacesTestUtils.setFaviconForPage(entry.page, entry.icon, dataUrl);
Assert.equal(
await getFaviconUrlForPage(entry.page),
entry.icon,
@@ -380,13 +374,7 @@ add_task(async function test_expire_icons() {
}
if (entry.root) {
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
- Services.io.newURI(entry.root),
- dataUrl,
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- await PlacesTestUtils.addFavicons(new Map([[entry.page, entry.root]]));
+ await PlacesTestUtils.setFaviconForPage(entry.page, entry.root, dataUrl);
}
if (entry.iconExpired) {
diff --git a/toolkit/components/places/tests/favicons/head_favicons.js b/toolkit/components/places/tests/favicons/head_favicons.js
index afd2c4924f..73dd2a61ed 100644
--- a/toolkit/components/places/tests/favicons/head_favicons.js
+++ b/toolkit/components/places/tests/favicons/head_favicons.js
@@ -15,6 +15,9 @@
const systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
+// Used in createFavicon().
+let uniqueFaviconId = 0;
+
/**
* Checks that the favicon for the given page matches the provided data.
*
@@ -24,6 +27,7 @@ const systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
* Expected MIME type of the icon, for example "image/png".
* @param aExpectedData
* Expected icon data, expressed as an array of byte values.
+ * If set null, skip the test for the favicon data.
* @param aCallback
* This function is called after the check finished.
*/
@@ -37,7 +41,9 @@ function checkFaviconDataForPage(
aPageURI,
async function (aURI, aDataLen, aData, aMimeType) {
Assert.equal(aExpectedMimeType, aMimeType);
- Assert.ok(compareArrays(aExpectedData, aData));
+ if (aExpectedData) {
+ Assert.ok(compareArrays(aExpectedData, aData));
+ }
await check_guid_for_uri(aPageURI);
aCallback();
}
@@ -76,3 +82,82 @@ function promiseFaviconChanged(aExpectedPageURI, aExpectedFaviconURI) {
});
});
}
+
+/**
+ * Create favicon file to temp directory.
+ *
+ * @param {string} aFileName
+ * File name that will be created in temp directory.
+ * @returns {object}
+ * {
+ * file: nsIFile,
+ * uri: nsIURI,
+ * data: byte Array,
+ * mimetype: String,
+ * }
+ */
+async function createFavicon(aFileName) {
+ // Copy the favicon file we have to the specified file in temp directory.
+ let originalFaviconFile = do_get_file("favicon-normal16.png");
+ let tempDir = Services.dirsvc.get("TmpD", Ci.nsIFile);
+ let faviconFile = tempDir.clone();
+ faviconFile.append(aFileName);
+ await IOUtils.copy(originalFaviconFile.path, faviconFile.path);
+
+ // Append some data that sniffers/encoders will ignore that will distinguish
+ // the different favicons we'll create.
+ let stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
+ Ci.nsIFileOutputStream
+ );
+ const WRONLY_PERMISSION = 0o600;
+ stream.init(
+ faviconFile,
+ FileUtils.MODE_WRONLY | FileUtils.MODE_APPEND,
+ WRONLY_PERMISSION,
+ 0
+ );
+ uniqueFaviconId++;
+ let uniqueStr = "uid:" + uniqueFaviconId;
+ stream.write(uniqueStr, uniqueStr.length);
+ stream.close();
+
+ Assert.equal(faviconFile.leafName.substr(0, aFileName.length), aFileName);
+
+ return {
+ file: faviconFile,
+ uri: uri(faviconFile),
+ data: readFileData(faviconFile),
+ mimeType: "image/png",
+ };
+}
+
+/**
+ * Create nsIURI for given favicon object.
+ *
+ * @param {object} aFavicon
+ * Favicon object created by createFavicon().
+ * @returns {nsIURI}
+ */
+async function createDataURLForFavicon(aFavicon) {
+ let dataURL = await toDataURL(aFavicon.data, aFavicon.mimeType);
+ return uri(dataURL);
+}
+
+/**
+ * Create data URL string from given byte array and type.
+ *
+ * @param {Array} data
+ * Byte array.
+ * @param {string} type
+ * The type of this data.
+ * @returns {string}
+ */
+function toDataURL(data, type) {
+ let blob = new Blob([new Uint8Array(data)], { type });
+ return new Promise((resolve, reject) => {
+ let reader = new FileReader();
+ reader.addEventListener("load", () => resolve(reader.result));
+ reader.addEventListener("error", reject);
+ reader.readAsDataURL(blob);
+ });
+}
diff --git a/toolkit/components/places/tests/favicons/test_cached-favicon_mime_type.js b/toolkit/components/places/tests/favicons/test_cached-favicon_mime_type.js
index c1f6689a70..52eb81ae85 100644
--- a/toolkit/components/places/tests/favicons/test_cached-favicon_mime_type.js
+++ b/toolkit/components/places/tests/favicons/test_cached-favicon_mime_type.js
@@ -68,14 +68,12 @@ add_task(async function () {
info("Test that the content type of a favicon we add is correct.");
let testURI = uri("http://mozilla.org/");
// Add the data before opening
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.addVisits(testURI);
+ await PlacesTestUtils.setFaviconForPage(
+ testURI,
testIconURI,
- testFaviconData,
- 0,
- systemPrincipal
+ testFaviconData
);
- await PlacesTestUtils.addVisits(testURI);
- await setFaviconForPage(testURI, testIconURI);
// Open the channel
let channel = NetUtil.newChannel({
uri: PlacesUtils.favicons.getFaviconLinkForIcon(testIconURI).spec,
@@ -120,14 +118,12 @@ add_task(async function test_userpass() {
CACHED_ICON_NORMAL,
CACHED_ICON_USERPASS,
]) {
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.addVisits(pageURI);
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI,
iconURI,
- testFaviconData,
- 0,
- systemPrincipal
+ testFaviconData
);
- await PlacesTestUtils.addVisits(pageURI);
- await setFaviconForPage(pageURI, iconURI);
// Open the channel
let channel = NetUtil.newChannel({
diff --git a/toolkit/components/places/tests/favicons/test_expire_on_new_icons.js b/toolkit/components/places/tests/favicons/test_expire_on_new_icons.js
index d5a7c42ba3..f0089d737b 100644
--- a/toolkit/components/places/tests/favicons/test_expire_on_new_icons.js
+++ b/toolkit/components/places/tests/favicons/test_expire_on_new_icons.js
@@ -28,23 +28,23 @@ add_task(async function test_expire_associated() {
];
for (let icon of favicons) {
- let data = readFileData(do_get_file(icon.name));
- PlacesUtils.favicons.replaceFaviconData(
- NetUtil.newURI(TEST_URL + icon.name),
- data,
+ let dataURL = await readFileDataAsDataURL(
+ do_get_file(icon.name),
icon.mimeType
);
- await setFaviconForPage(TEST_URL, TEST_URL + icon.name);
+ await PlacesTestUtils.setFaviconForPage(
+ TEST_URL,
+ TEST_URL + icon.name,
+ dataURL
+ );
if (icon.expired) {
await expireIconRelationsForPage(TEST_URL);
// Add the same icon to another page.
- PlacesUtils.favicons.replaceFaviconData(
- NetUtil.newURI(TEST_URL + icon.name),
- data,
- icon.mimeType,
- icon.expire
+ await PlacesTestUtils.setFaviconForPage(
+ TEST_URL2,
+ TEST_URL + icon.name,
+ dataURL
);
- await setFaviconForPage(TEST_URL2, TEST_URL + icon.name);
}
}
@@ -88,13 +88,7 @@ add_task(async function test_expire_root() {
// Insert an expired icon.
let iconURI = NetUtil.newURI(pageURI.spec + "favicon-normal16.png");
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
- iconURI,
- SMALLPNG_DATA_URI.spec,
- 0,
- systemPrincipal
- );
- await setFaviconForPage(pageURI, iconURI);
+ await PlacesTestUtils.setFaviconForPage(pageURI, iconURI, SMALLPNG_DATA_URI);
Assert.equal(
await countEntries("moz_icons_to_pages"),
1,
@@ -105,13 +99,11 @@ add_task(async function test_expire_root() {
// Now insert a new root icon.
let rootIconURI = NetUtil.newURI(pageURI.spec + "favicon.ico");
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI,
rootIconURI,
- SMALLPNG_DATA_URI.spec,
- 0,
- systemPrincipal
+ SMALLPNG_DATA_URI
);
- await setFaviconForPage(pageURI, rootIconURI);
// Only the root icon should have survived.
Assert.equal(
diff --git a/toolkit/components/places/tests/favicons/test_favicons_conversions.js b/toolkit/components/places/tests/favicons/test_favicons_conversions.js
index 28a0fffb7f..dd8a35c5ac 100644
--- a/toolkit/components/places/tests/favicons/test_favicons_conversions.js
+++ b/toolkit/components/places/tests/favicons/test_favicons_conversions.js
@@ -43,29 +43,24 @@ async function checkFaviconDataConversion(
});
let faviconURI = NetUtil.newURI("http://places.test/icon/" + aFileName);
let fileData = readFileOfLength(aFileName, aFileLength);
+ let fileDataURL = await fileDataToDataURL(fileData, aFileMimeType);
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI.spec,
+ faviconURI.spec,
+ fileDataURL
+ );
- PlacesUtils.favicons.replaceFaviconData(faviconURI, fileData, aFileMimeType);
await new Promise(resolve => {
- PlacesUtils.favicons.setAndFetchFaviconForPage(
- pageURI,
- faviconURI,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- (aURI, aDataLen, aData, aMimeType) => {
- if (!aExpectConversion) {
- Assert.ok(compareArrays(aData, fileData));
- Assert.equal(aMimeType, aFileMimeType);
- } else {
- if (!aVaryOnWindows || !isWindows) {
- let expectedFile = do_get_file("expected-" + aFileName + ".png");
- Assert.ok(compareArrays(aData, readFileData(expectedFile)));
- }
- Assert.equal(aMimeType, "image/png");
- }
- resolve();
- },
- Services.scriptSecurityManager.getSystemPrincipal()
- );
+ if (!aExpectConversion) {
+ checkFaviconDataForPage(pageURI, aFileMimeType, fileData, resolve);
+ } else if (!aVaryOnWindows || !isWindows) {
+ let expectedFile = do_get_file("expected-" + aFileName + ".png");
+ let expectedData = readFileData(expectedFile);
+ checkFaviconDataForPage(pageURI, "image/png", expectedData, resolve);
+ } else {
+ // Not check the favicon data.
+ checkFaviconDataForPage(pageURI, "image/png", null, resolve);
+ }
});
}
diff --git a/toolkit/components/places/tests/favicons/test_favicons_protocols_ref.js b/toolkit/components/places/tests/favicons/test_favicons_protocols_ref.js
index aa0241a3d2..4d359f7307 100644
--- a/toolkit/components/places/tests/favicons/test_favicons_protocols_ref.js
+++ b/toolkit/components/places/tests/favicons/test_favicons_protocols_ref.js
@@ -9,21 +9,16 @@ const ICON32_URL = "http://places.test/favicon-normal32.png";
add_task(async function () {
await PlacesTestUtils.addVisits(PAGE_URL);
// Add 2 differently sized favicons for this page.
-
- let data = readFileData(do_get_file("favicon-normal16.png"));
- PlacesUtils.favicons.replaceFaviconData(
- Services.io.newURI(ICON16_URL),
- data,
+ let dataURL16 = await readFileDataAsDataURL(
+ do_get_file("favicon-normal16.png"),
"image/png"
);
- await setFaviconForPage(PAGE_URL, ICON16_URL);
- data = readFileData(do_get_file("favicon-normal32.png"));
- PlacesUtils.favicons.replaceFaviconData(
- Services.io.newURI(ICON32_URL),
- data,
+ await PlacesTestUtils.setFaviconForPage(PAGE_URL, ICON16_URL, dataURL16);
+ let dataURL32 = await readFileDataAsDataURL(
+ do_get_file("favicon-normal32.png"),
"image/png"
);
- await setFaviconForPage(PAGE_URL, ICON32_URL);
+ await PlacesTestUtils.setFaviconForPage(PAGE_URL, ICON32_URL, dataURL32);
const PAGE_ICON_URL = "page-icon:" + PAGE_URL;
diff --git a/toolkit/components/places/tests/favicons/test_getFaviconDataForPage.js b/toolkit/components/places/tests/favicons/test_getFaviconDataForPage.js
index 80f498f33f..8c6fb0a2bb 100644
--- a/toolkit/components/places/tests/favicons/test_getFaviconDataForPage.js
+++ b/toolkit/components/places/tests/favicons/test_getFaviconDataForPage.js
@@ -60,12 +60,8 @@ add_task(async function test_fallback() {
info("Set icon for the root");
await PlacesTestUtils.addVisits(ROOT_URL);
let data = readFileData(do_get_file("favicon-normal16.png"));
- PlacesUtils.favicons.replaceFaviconData(
- NetUtil.newURI(ROOT_ICON_URL),
- data,
- "image/png"
- );
- await setFaviconForPage(ROOT_URL, ROOT_ICON_URL);
+ let dataURL = await fileDataToDataURL(data, "image/png");
+ await PlacesTestUtils.setFaviconForPage(ROOT_URL, ROOT_ICON_URL, dataURL);
info("check fallback icons");
await new Promise(resolve => {
@@ -96,12 +92,8 @@ add_task(async function test_fallback() {
info("Now add a proper icon for the page");
await PlacesTestUtils.addVisits(SUBPAGE_URL);
let data32 = readFileData(do_get_file("favicon-normal32.png"));
- PlacesUtils.favicons.replaceFaviconData(
- NetUtil.newURI(ICON32_URL),
- data32,
- "image/png"
- );
- await setFaviconForPage(SUBPAGE_URL, ICON32_URL);
+ let dataURL32 = await fileDataToDataURL(data32, "image/png");
+ await PlacesTestUtils.setFaviconForPage(SUBPAGE_URL, ICON32_URL, dataURL32);
info("check no fallback icons");
await new Promise(resolve => {
diff --git a/toolkit/components/places/tests/favicons/test_getFaviconURLForPage.js b/toolkit/components/places/tests/favicons/test_getFaviconURLForPage.js
index e8f459cb08..3fa11ae6c0 100644
--- a/toolkit/components/places/tests/favicons/test_getFaviconURLForPage.js
+++ b/toolkit/components/places/tests/favicons/test_getFaviconURLForPage.js
@@ -57,13 +57,11 @@ add_task(async function test_fallback() {
info("Set icon for the root");
await PlacesTestUtils.addVisits(ROOT_URL);
- let data = readFileData(do_get_file("favicon-normal16.png"));
- PlacesUtils.favicons.replaceFaviconData(
- NetUtil.newURI(ROOT_ICON_URL),
- data,
+ let dataURL = await readFileDataAsDataURL(
+ do_get_file("favicon-normal16.png"),
"image/png"
);
- await setFaviconForPage(ROOT_URL, ROOT_ICON_URL);
+ await PlacesTestUtils.setFaviconForPage(ROOT_URL, ROOT_ICON_URL, dataURL);
info("check fallback icons");
Assert.equal(
@@ -79,13 +77,11 @@ add_task(async function test_fallback() {
info("Now add a proper icon for the page");
await PlacesTestUtils.addVisits(SUBPAGE_URL);
- let data32 = readFileData(do_get_file("favicon-normal32.png"));
- PlacesUtils.favicons.replaceFaviconData(
- NetUtil.newURI(ICON32_URL),
- data32,
+ let dataURL32 = await readFileDataAsDataURL(
+ do_get_file("favicon-normal32.png"),
"image/png"
);
- await setFaviconForPage(SUBPAGE_URL, ICON32_URL);
+ await PlacesTestUtils.setFaviconForPage(SUBPAGE_URL, ICON32_URL, dataURL32);
info("check no fallback icons");
Assert.equal(
diff --git a/toolkit/components/places/tests/favicons/test_heavy_favicon.js b/toolkit/components/places/tests/favicons/test_heavy_favicon.js
index 09adcaf6fa..4541de9bff 100644
--- a/toolkit/components/places/tests/favicons/test_heavy_favicon.js
+++ b/toolkit/components/places/tests/favicons/test_heavy_favicon.js
@@ -26,8 +26,8 @@ add_task(async function () {
let pageURI = uri("http://foo.bar/");
await PlacesTestUtils.addVisits(pageURI);
- PlacesUtils.favicons.replaceFaviconData(icon.uri, icon.data, icon.mimetype);
- await setFaviconForPage(pageURI, icon.uri);
+ let dataURI = await fileDataToDataURL(icon.data, icon.mimetype);
+ await PlacesTestUtils.setFaviconForPage(pageURI.spec, icon.uri.spec, dataURI);
Assert.equal(
await getFaviconUrlForPage(pageURI),
icon.uri.spec,
diff --git a/toolkit/components/places/tests/favicons/test_incremental_vacuum.js b/toolkit/components/places/tests/favicons/test_incremental_vacuum.js
index ab93121d47..2c1a5ad3f9 100644
--- a/toolkit/components/places/tests/favicons/test_incremental_vacuum.js
+++ b/toolkit/components/places/tests/favicons/test_incremental_vacuum.js
@@ -16,10 +16,9 @@ add_task(async function () {
let url = "http://foo.bar/";
await PlacesTestUtils.addVisits(url);
for (let i = 0; i < 10; ++i) {
- let iconUri = NetUtil.newURI("http://mozilla.org/" + i);
- let data = readFileData(icon.file);
- PlacesUtils.favicons.replaceFaviconData(iconUri, data, icon.mimetype);
- await setFaviconForPage(url, iconUri);
+ let iconUri = "http://mozilla.org/" + i;
+ let dataURL = await readFileDataAsDataURL(icon.file, icon.mimetype);
+ await PlacesTestUtils.setFaviconForPage(url, iconUri, dataURL);
}
let promise = TestUtils.topicObserved("places-favicons-expired");
diff --git a/toolkit/components/places/tests/favicons/test_multiple_frames.js b/toolkit/components/places/tests/favicons/test_multiple_frames.js
index 5c7f585715..a6aae572de 100644
--- a/toolkit/components/places/tests/favicons/test_multiple_frames.js
+++ b/toolkit/components/places/tests/favicons/test_multiple_frames.js
@@ -14,9 +14,15 @@ add_task(async function () {
let faviconURI = NetUtil.newURI("http://places.test/icon/favicon-multi.ico");
// Fake window.
let win = { devicePixelRatio: 1.0 };
- let icoData = readFileData(do_get_file("favicon-multi.ico"));
- PlacesUtils.favicons.replaceFaviconData(faviconURI, icoData, "image/x-icon");
- await setFaviconForPage(pageURI, faviconURI);
+ let icoDataURL = await readFileDataAsDataURL(
+ do_get_file("favicon-multi.ico"),
+ "image/x-icon"
+ );
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI.spec,
+ faviconURI.spec,
+ icoDataURL
+ );
for (let size of [16, 32, 64]) {
let file = do_get_file(`favicon-multi-frame${size}.png`);
diff --git a/toolkit/components/places/tests/favicons/test_page-icon_protocol.js b/toolkit/components/places/tests/favicons/test_page-icon_protocol.js
index 287484868f..2241dec990 100644
--- a/toolkit/components/places/tests/favicons/test_page-icon_protocol.js
+++ b/toolkit/components/places/tests/favicons/test_page-icon_protocol.js
@@ -76,25 +76,12 @@ var gFavicon;
add_task(async function setup() {
await PlacesTestUtils.addVisits(TEST_URI);
-
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.setFaviconForPage(
+ TEST_URI,
ICON_URI,
ICON_DATAURL,
- (Date.now() + 8640000) * 1000,
- Services.scriptSecurityManager.getSystemPrincipal()
+ (Date.now() + 8640000) * 1000
);
-
- await new Promise(resolve => {
- PlacesUtils.favicons.setAndFetchFaviconForPage(
- TEST_URI,
- ICON_URI,
- false,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- resolve,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
-
gDefaultFavicon = await fetchIconForSpec(
PlacesUtils.favicons.defaultFavicon.spec
);
@@ -133,13 +120,11 @@ add_task(async function subpage_url_fallback() {
add_task(async function svg_icon() {
let faviconURI = NetUtil.newURI("http://places.test/favicon.svg");
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.setFaviconForPage(
+ TEST_URI,
faviconURI,
- SMALLSVG_DATA_URI.spec,
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
+ SMALLSVG_DATA_URI
);
- await setFaviconForPage(TEST_URI, faviconURI);
let svgIcon = await fetchIconForSpec(SMALLSVG_DATA_URI.spec);
info(svgIcon.contentType);
let pageIcon = await fetchIconForSpec("page-icon:" + TEST_URI.spec);
@@ -270,23 +255,8 @@ add_task(async function test_with_user_pass() {
for (const { pageURI, iconURI } of testData) {
for (const loadingIconURISpec of [PAGE_ICON_NORMAL, PAGE_ICON_USERPASS]) {
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
- iconURI,
- ICON_DATAURL,
- 0,
- systemPrincipal
- );
await PlacesTestUtils.addVisits(pageURI);
- await new Promise(resolve => {
- PlacesUtils.favicons.setAndFetchFaviconForPage(
- pageURI,
- iconURI,
- false,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- resolve,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
+ await PlacesTestUtils.setFaviconForPage(pageURI, iconURI, ICON_DATAURL);
let { data, contentType } = await fetchIconForSpec(loadingIconURISpec);
Assert.equal(contentType, gFavicon.contentType);
diff --git a/toolkit/components/places/tests/favicons/test_replaceFaviconData.js b/toolkit/components/places/tests/favicons/test_replaceFaviconData.js
deleted file mode 100644
index 2e9835eaa9..0000000000
--- a/toolkit/components/places/tests/favicons/test_replaceFaviconData.js
+++ /dev/null
@@ -1,395 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Tests for replaceFaviconData()
- */
-
-var iconsvc = PlacesUtils.favicons;
-
-var originalFavicon = {
- file: do_get_file("favicon-normal16.png"),
- uri: uri(do_get_file("favicon-normal16.png")),
- data: readFileData(do_get_file("favicon-normal16.png")),
- mimetype: "image/png",
-};
-
-var uniqueFaviconId = 0;
-function createFavicon(fileName) {
- let tempdir = Services.dirsvc.get("TmpD", Ci.nsIFile);
-
- // remove any existing file at the path we're about to copy to
- let outfile = tempdir.clone();
- outfile.append(fileName);
- try {
- outfile.remove(false);
- } catch (e) {}
-
- originalFavicon.file.copyToFollowingLinks(tempdir, fileName);
-
- let stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
- Ci.nsIFileOutputStream
- );
- stream.init(outfile, 0x02 | 0x08 | 0x10, 0o600, 0);
-
- // append some data that sniffers/encoders will ignore that will distinguish
- // the different favicons we'll create
- uniqueFaviconId++;
- let uniqueStr = "uid:" + uniqueFaviconId;
- stream.write(uniqueStr, uniqueStr.length);
- stream.close();
-
- Assert.equal(outfile.leafName.substr(0, fileName.length), fileName);
-
- return {
- file: outfile,
- uri: uri(outfile),
- data: readFileData(outfile),
- mimetype: "image/png",
- };
-}
-
-function checkCallbackSucceeded(
- callbackMimetype,
- callbackData,
- sourceMimetype,
- sourceData
-) {
- Assert.equal(callbackMimetype, sourceMimetype);
- Assert.ok(compareArrays(callbackData, sourceData));
-}
-
-function run_test() {
- // check that the favicon loaded correctly
- Assert.equal(originalFavicon.data.length, 286);
- run_next_test();
-}
-
-add_task(async function test_replaceFaviconData_validHistoryURI() {
- info("test replaceFaviconData for valid history uri");
-
- let pageURI = uri("http://test1.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let favicon = createFavicon("favicon1.png");
-
- iconsvc.replaceFaviconData(favicon.uri, favicon.data, favicon.mimetype);
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- favicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconData_validHistoryURI_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- dump("GOT " + aMimeType + "\n");
- checkCallbackSucceeded(
- aMimeType,
- aData,
- favicon.mimetype,
- favicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- favicon.mimetype,
- favicon.data,
- function test_replaceFaviconData_validHistoryURI_callback() {
- favicon.file.remove(false);
- resolve();
- }
- );
- },
- systemPrincipal
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconData_overrideDefaultFavicon() {
- info("test replaceFaviconData to override a later setAndFetchFaviconForPage");
-
- let pageURI = uri("http://test2.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let firstFavicon = createFavicon("favicon2.png");
- let secondFavicon = createFavicon("favicon3.png");
-
- iconsvc.replaceFaviconData(
- firstFavicon.uri,
- secondFavicon.data,
- secondFavicon.mimetype
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- firstFavicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconData_overrideDefaultFavicon_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- secondFavicon.mimetype,
- secondFavicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- secondFavicon.mimetype,
- secondFavicon.data,
- function test_replaceFaviconData_overrideDefaultFavicon_callback() {
- firstFavicon.file.remove(false);
- secondFavicon.file.remove(false);
- resolve();
- }
- );
- },
- systemPrincipal
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconData_replaceExisting() {
- info(
- "test replaceFaviconData to override a previous setAndFetchFaviconForPage"
- );
-
- let pageURI = uri("http://test3.bar");
- await PlacesTestUtils.addVisits(pageURI);
-
- let firstFavicon = createFavicon("favicon4.png");
- let secondFavicon = createFavicon("favicon5.png");
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- firstFavicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconData_replaceExisting_firstSet_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- firstFavicon.mimetype,
- firstFavicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- firstFavicon.mimetype,
- firstFavicon.data,
- function test_replaceFaviconData_overrideDefaultFavicon_firstCallback() {
- iconsvc.replaceFaviconData(
- firstFavicon.uri,
- secondFavicon.data,
- secondFavicon.mimetype
- );
- PlacesTestUtils.promiseAsyncUpdates().then(() => {
- checkFaviconDataForPage(
- pageURI,
- secondFavicon.mimetype,
- secondFavicon.data,
- function test_replaceFaviconData_overrideDefaultFavicon_secondCallback() {
- firstFavicon.file.remove(false);
- secondFavicon.file.remove(false);
- resolve();
- },
- systemPrincipal
- );
- });
- }
- );
- },
- systemPrincipal
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconData_unrelatedReplace() {
- info("test replaceFaviconData to not make unrelated changes");
-
- let pageURI = uri("http://test4.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let favicon = createFavicon("favicon6.png");
- let unrelatedFavicon = createFavicon("favicon7.png");
-
- iconsvc.replaceFaviconData(
- unrelatedFavicon.uri,
- unrelatedFavicon.data,
- unrelatedFavicon.mimetype
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- favicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconData_unrelatedReplace_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- favicon.mimetype,
- favicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- favicon.mimetype,
- favicon.data,
- function test_replaceFaviconData_unrelatedReplace_callback() {
- favicon.file.remove(false);
- unrelatedFavicon.file.remove(false);
- resolve();
- }
- );
- },
- systemPrincipal
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconData_badInputs() {
- info("test replaceFaviconData to throw on bad inputs");
- let icon = createFavicon("favicon8.png");
-
- Assert.throws(
- () => iconsvc.replaceFaviconData(icon.uri, icon.data, ""),
- /NS_ERROR_ILLEGAL_VALUE/
- );
- Assert.throws(
- () => iconsvc.replaceFaviconData(icon.uri, icon.data, "not-an-image"),
- /NS_ERROR_ILLEGAL_VALUE/
- );
- Assert.throws(
- () => iconsvc.replaceFaviconData(null, icon.data, icon.mimetype),
- /NS_ERROR_ILLEGAL_VALUE/
- );
- Assert.throws(
- () => iconsvc.replaceFaviconData(icon.uri, [], icon.mimetype),
- /NS_ERROR_ILLEGAL_VALUE/
- );
- Assert.throws(
- () => iconsvc.replaceFaviconData(icon.uri, null, icon.mimetype),
- /NS_ERROR_XPC_CANT_CONVERT_PRIMITIVE_TO_ARRAY/
- );
-
- icon.file.remove(false);
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconData_twiceReplace() {
- info("test replaceFaviconData on multiple replacements");
-
- let pageURI = uri("http://test5.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let firstFavicon = createFavicon("favicon9.png");
- let secondFavicon = createFavicon("favicon10.png");
-
- iconsvc.replaceFaviconData(
- firstFavicon.uri,
- firstFavicon.data,
- firstFavicon.mimetype
- );
- iconsvc.replaceFaviconData(
- firstFavicon.uri,
- secondFavicon.data,
- secondFavicon.mimetype
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- firstFavicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconData_twiceReplace_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- secondFavicon.mimetype,
- secondFavicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- secondFavicon.mimetype,
- secondFavicon.data,
- function test_replaceFaviconData_twiceReplace_callback() {
- firstFavicon.file.remove(false);
- secondFavicon.file.remove(false);
- resolve();
- },
- systemPrincipal
- );
- },
- systemPrincipal
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconData_rootOverwrite() {
- info("test replaceFaviconData doesn't overwrite root = 1");
-
- async function getRootValue(url) {
- let db = await PlacesUtils.promiseDBConnection();
- let rows = await db.execute(
- "SELECT root FROM moz_icons WHERE icon_url = :url",
- { url }
- );
- return rows[0].getResultByName("root");
- }
-
- const PAGE_URL = "http://rootoverwrite.bar/";
- let pageURI = Services.io.newURI(PAGE_URL);
- const ICON_URL = "http://rootoverwrite.bar/favicon.ico";
- let iconURI = Services.io.newURI(ICON_URL);
-
- await PlacesTestUtils.addVisits(pageURI);
-
- let icon = createFavicon("favicon9.png");
- PlacesUtils.favicons.replaceFaviconData(iconURI, icon.data, icon.mimetype);
- await PlacesTestUtils.addFavicons(new Map([[PAGE_URL, ICON_URL]]));
-
- Assert.equal(await getRootValue(ICON_URL), 1, "Check root == 1");
- let icon2 = createFavicon("favicon10.png");
- PlacesUtils.favicons.replaceFaviconData(iconURI, icon2.data, icon2.mimetype);
- // replaceFaviconData doesn't have a callback, but we must wait its updated.
- await PlacesTestUtils.promiseAsyncUpdates();
- Assert.equal(await getRootValue(ICON_URL), 1, "Check root did not change");
-
- await PlacesUtils.history.clear();
-});
diff --git a/toolkit/components/places/tests/favicons/test_replaceFaviconDataFromDataURL.js b/toolkit/components/places/tests/favicons/test_replaceFaviconDataFromDataURL.js
deleted file mode 100644
index c1b83fc8a7..0000000000
--- a/toolkit/components/places/tests/favicons/test_replaceFaviconDataFromDataURL.js
+++ /dev/null
@@ -1,537 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/*
- * Tests for replaceFaviconData()
- */
-
-var iconsvc = PlacesUtils.favicons;
-
-var originalFavicon = {
- file: do_get_file("favicon-normal16.png"),
- uri: uri(do_get_file("favicon-normal16.png")),
- data: readFileData(do_get_file("favicon-normal16.png")),
- mimetype: "image/png",
-};
-
-var uniqueFaviconId = 0;
-function createFavicon(fileName) {
- let tempdir = Services.dirsvc.get("TmpD", Ci.nsIFile);
-
- // remove any existing file at the path we're about to copy to
- let outfile = tempdir.clone();
- outfile.append(fileName);
- try {
- outfile.remove(false);
- } catch (e) {}
-
- originalFavicon.file.copyToFollowingLinks(tempdir, fileName);
-
- let stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
- Ci.nsIFileOutputStream
- );
- stream.init(outfile, 0x02 | 0x08 | 0x10, 0o600, 0);
-
- // append some data that sniffers/encoders will ignore that will distinguish
- // the different favicons we'll create
- uniqueFaviconId++;
- let uniqueStr = "uid:" + uniqueFaviconId;
- stream.write(uniqueStr, uniqueStr.length);
- stream.close();
-
- Assert.equal(outfile.leafName.substr(0, fileName.length), fileName);
-
- return {
- file: outfile,
- uri: uri(outfile),
- data: readFileData(outfile),
- mimetype: "image/png",
- };
-}
-
-function createDataURLForFavicon(favicon) {
- return "data:" + favicon.mimetype + ";base64," + toBase64(favicon.data);
-}
-
-function checkCallbackSucceeded(
- callbackMimetype,
- callbackData,
- sourceMimetype,
- sourceData
-) {
- Assert.equal(callbackMimetype, sourceMimetype);
- Assert.ok(compareArrays(callbackData, sourceData));
-}
-
-function run_test() {
- // check that the favicon loaded correctly
- Assert.equal(originalFavicon.data.length, 286);
- run_next_test();
-}
-
-add_task(async function test_replaceFaviconDataFromDataURL_validHistoryURI() {
- info("test replaceFaviconDataFromDataURL for valid history uri");
-
- let pageURI = uri("http://test1.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let favicon = createFavicon("favicon1.png");
- iconsvc.replaceFaviconDataFromDataURL(
- favicon.uri,
- createDataURLForFavicon(favicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- favicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconDataFromDataURL_validHistoryURI_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- favicon.mimetype,
- favicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- favicon.mimetype,
- favicon.data,
- function test_replaceFaviconDataFromDataURL_validHistoryURI_callback() {
- favicon.file.remove(false);
- resolve();
- }
- );
- },
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(
- async function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon() {
- info(
- "test replaceFaviconDataFromDataURL to override a later setAndFetchFaviconForPage"
- );
-
- let pageURI = uri("http://test2.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let firstFavicon = createFavicon("favicon2.png");
- let secondFavicon = createFavicon("favicon3.png");
-
- iconsvc.replaceFaviconDataFromDataURL(
- firstFavicon.uri,
- createDataURLForFavicon(secondFavicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- firstFavicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- secondFavicon.mimetype,
- secondFavicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- secondFavicon.mimetype,
- secondFavicon.data,
- function test_replaceFaviconDataFromDataURL_overrideDefaultFavicon_callback() {
- firstFavicon.file.remove(false);
- secondFavicon.file.remove(false);
- resolve();
- }
- );
- },
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
-
- await PlacesUtils.history.clear();
- }
-);
-
-add_task(async function test_replaceFaviconDataFromDataURL_replaceExisting() {
- info(
- "test replaceFaviconDataFromDataURL to override a previous setAndFetchFaviconForPage"
- );
-
- let pageURI = uri("http://test3.bar");
- await PlacesTestUtils.addVisits(pageURI);
-
- let firstFavicon = createFavicon("favicon4.png");
- let secondFavicon = createFavicon("favicon5.png");
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- firstFavicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconDataFromDataURL_replaceExisting_firstSet_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- firstFavicon.mimetype,
- firstFavicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- firstFavicon.mimetype,
- firstFavicon.data,
- function test_replaceFaviconDataFromDataURL_replaceExisting_firstCallback() {
- iconsvc.replaceFaviconDataFromDataURL(
- firstFavicon.uri,
- createDataURLForFavicon(secondFavicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- checkFaviconDataForPage(
- pageURI,
- secondFavicon.mimetype,
- secondFavicon.data,
- function test_replaceFaviconDataFromDataURL_replaceExisting_secondCallback() {
- firstFavicon.file.remove(false);
- secondFavicon.file.remove(false);
- resolve();
- }
- );
- }
- );
- },
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconDataFromDataURL_unrelatedReplace() {
- info("test replaceFaviconDataFromDataURL to not make unrelated changes");
-
- let pageURI = uri("http://test4.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let favicon = createFavicon("favicon6.png");
- let unrelatedFavicon = createFavicon("favicon7.png");
-
- iconsvc.replaceFaviconDataFromDataURL(
- unrelatedFavicon.uri,
- createDataURLForFavicon(unrelatedFavicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- favicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconDataFromDataURL_unrelatedReplace_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- favicon.mimetype,
- favicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- favicon.mimetype,
- favicon.data,
- function test_replaceFaviconDataFromDataURL_unrelatedReplace_callback() {
- favicon.file.remove(false);
- unrelatedFavicon.file.remove(false);
- resolve();
- }
- );
- },
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconDataFromDataURL_badInputs() {
- info("test replaceFaviconDataFromDataURL to throw on bad inputs");
-
- let favicon = createFavicon("favicon8.png");
-
- let ex = null;
- try {
- iconsvc.replaceFaviconDataFromDataURL(
- favicon.uri,
- "",
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- } catch (e) {
- ex = e;
- } finally {
- Assert.ok(!!ex);
- }
-
- ex = null;
- try {
- iconsvc.replaceFaviconDataFromDataURL(
- null,
- createDataURLForFavicon(favicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- } catch (e) {
- ex = e;
- } finally {
- Assert.ok(!!ex);
- }
-
- favicon.file.remove(false);
-
- await PlacesUtils.history.clear();
-});
-
-add_task(async function test_replaceFaviconDataFromDataURL_twiceReplace() {
- info("test replaceFaviconDataFromDataURL on multiple replacements");
-
- let pageURI = uri("http://test5.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let firstFavicon = createFavicon("favicon9.png");
- let secondFavicon = createFavicon("favicon10.png");
-
- iconsvc.replaceFaviconDataFromDataURL(
- firstFavicon.uri,
- createDataURLForFavicon(firstFavicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- iconsvc.replaceFaviconDataFromDataURL(
- firstFavicon.uri,
- createDataURLForFavicon(secondFavicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- firstFavicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconDataFromDataURL_twiceReplace_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- secondFavicon.mimetype,
- secondFavicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- secondFavicon.mimetype,
- secondFavicon.data,
- function test_replaceFaviconDataFromDataURL_twiceReplace_callback() {
- firstFavicon.file.remove(false);
- secondFavicon.file.remove(false);
- resolve();
- }
- );
- },
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
-
- await PlacesUtils.history.clear();
-});
-
-add_task(
- async function test_replaceFaviconDataFromDataURL_afterRegularAssign() {
- info("test replaceFaviconDataFromDataURL after replaceFaviconData");
-
- let pageURI = uri("http://test6.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let firstFavicon = createFavicon("favicon11.png");
- let secondFavicon = createFavicon("favicon12.png");
-
- iconsvc.replaceFaviconData(
- firstFavicon.uri,
- firstFavicon.data,
- firstFavicon.mimetype
- );
- iconsvc.replaceFaviconDataFromDataURL(
- firstFavicon.uri,
- createDataURLForFavicon(secondFavicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- firstFavicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconDataFromDataURL_afterRegularAssign_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- secondFavicon.mimetype,
- secondFavicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- secondFavicon.mimetype,
- secondFavicon.data,
- function test_replaceFaviconDataFromDataURL_afterRegularAssign_callback() {
- firstFavicon.file.remove(false);
- secondFavicon.file.remove(false);
- resolve();
- }
- );
- },
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
-
- await PlacesUtils.history.clear();
- }
-);
-
-add_task(
- async function test_replaceFaviconDataFromDataURL_beforeRegularAssign() {
- info("test replaceFaviconDataFromDataURL before replaceFaviconData");
-
- let pageURI = uri("http://test7.bar/");
- await PlacesTestUtils.addVisits(pageURI);
-
- let firstFavicon = createFavicon("favicon13.png");
- let secondFavicon = createFavicon("favicon14.png");
-
- iconsvc.replaceFaviconDataFromDataURL(
- firstFavicon.uri,
- createDataURLForFavicon(firstFavicon),
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- iconsvc.replaceFaviconData(
- firstFavicon.uri,
- secondFavicon.data,
- secondFavicon.mimetype
- );
-
- await new Promise(resolve => {
- iconsvc.setAndFetchFaviconForPage(
- pageURI,
- firstFavicon.uri,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- function test_replaceFaviconDataFromDataURL_beforeRegularAssign_check(
- aURI,
- aDataLen,
- aData,
- aMimeType
- ) {
- checkCallbackSucceeded(
- aMimeType,
- aData,
- secondFavicon.mimetype,
- secondFavicon.data
- );
- checkFaviconDataForPage(
- pageURI,
- secondFavicon.mimetype,
- secondFavicon.data,
- function test_replaceFaviconDataFromDataURL_beforeRegularAssign_callback() {
- firstFavicon.file.remove(false);
- secondFavicon.file.remove(false);
- resolve();
- }
- );
- },
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- });
-
- await PlacesUtils.history.clear();
- }
-);
-
-/* toBase64 copied from image/test/unit/test_encoder_png.js */
-
-/* Convert data (an array of integers) to a Base64 string. */
-const toBase64Table =
- // eslint-disable-next-line no-useless-concat
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789+/";
-const base64Pad = "=";
-function toBase64(data) {
- let result = "";
- let length = data.length;
- let i;
- // Convert every three bytes to 4 ascii characters.
- for (i = 0; i < length - 2; i += 3) {
- result += toBase64Table[data[i] >> 2];
- result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
- result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)];
- result += toBase64Table[data[i + 2] & 0x3f];
- }
-
- // Convert the remaining 1 or 2 bytes, pad out to 4 characters.
- if (length % 3) {
- i = length - (length % 3);
- result += toBase64Table[data[i] >> 2];
- if (length % 3 == 2) {
- result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)];
- result += toBase64Table[(data[i + 1] & 0x0f) << 2];
- result += base64Pad;
- } else {
- result += toBase64Table[(data[i] & 0x03) << 4];
- result += base64Pad + base64Pad;
- }
- }
-
- return result;
-}
diff --git a/toolkit/components/places/tests/favicons/test_root_icons.js b/toolkit/components/places/tests/favicons/test_root_icons.js
index f0487cc162..5a101ed6a6 100644
--- a/toolkit/components/places/tests/favicons/test_root_icons.js
+++ b/toolkit/components/places/tests/favicons/test_root_icons.js
@@ -9,13 +9,11 @@ add_task(async function () {
let pageURI = NetUtil.newURI("http://www.places.test/page/");
await PlacesTestUtils.addVisits(pageURI);
let faviconURI = NetUtil.newURI("http://www.places.test/favicon.ico");
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI,
faviconURI,
- SMALLPNG_DATA_URI.spec,
- 0,
- systemPrincipal
+ SMALLPNG_DATA_URI
);
- await setFaviconForPage(pageURI, faviconURI);
// Sanity checks.
Assert.equal(await getFaviconUrlForPage(pageURI), faviconURI.spec);
@@ -70,22 +68,18 @@ add_task(async function test_removePagesByTimeframe() {
// Add a normal icon to the most recent page.
let faviconURI = NetUtil.newURI(`${BASE_URL}/page/favicon.ico`);
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI,
faviconURI,
- SMALLSVG_DATA_URI.spec,
- 0,
- systemPrincipal
+ SMALLSVG_DATA_URI
);
- await setFaviconForPage(pageURI, faviconURI);
// Add a root icon to the most recent page.
let rootIconURI = NetUtil.newURI(`${BASE_URL}/favicon.ico`);
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI,
rootIconURI,
- SMALLPNG_DATA_URI.spec,
- 0,
- systemPrincipal
+ SMALLPNG_DATA_URI
);
- await setFaviconForPage(pageURI, rootIconURI);
// Sanity checks.
Assert.equal(
@@ -141,13 +135,11 @@ add_task(async function test_different_host() {
let pageURI = NetUtil.newURI("http://places.test/page/");
await PlacesTestUtils.addVisits(pageURI);
let faviconURI = NetUtil.newURI("http://mozilla.test/favicon.ico");
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI,
faviconURI,
- SMALLPNG_DATA_URI.spec,
- 0,
- systemPrincipal
+ SMALLPNG_DATA_URI
);
- await setFaviconForPage(pageURI, faviconURI);
Assert.equal(
await getFaviconUrlForPage(pageURI),
@@ -166,16 +158,25 @@ add_task(async function test_different_host() {
add_task(async function test_same_size() {
// Add two icons with the same size, one is a root icon. Check that the
// non-root icon is preferred when a smaller size is requested.
- let data = readFileData(do_get_file("favicon-normal32.png"));
+ let dataURL = await readFileDataAsDataURL(
+ do_get_file("favicon-normal32.png"),
+ "image/png"
+ );
let pageURI = NetUtil.newURI("http://new_places.test/page/");
await PlacesTestUtils.addVisits(pageURI);
let faviconURI = NetUtil.newURI("http://new_places.test/favicon.ico");
- PlacesUtils.favicons.replaceFaviconData(faviconURI, data, "image/png");
- await setFaviconForPage(pageURI, faviconURI);
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI.spec,
+ faviconURI.spec,
+ dataURL
+ );
faviconURI = NetUtil.newURI("http://new_places.test/another_icon.ico");
- PlacesUtils.favicons.replaceFaviconData(faviconURI, data, "image/png");
- await setFaviconForPage(pageURI, faviconURI);
+ await PlacesTestUtils.setFaviconForPage(
+ pageURI.spec,
+ faviconURI.spec,
+ dataURL
+ );
Assert.equal(
await getFaviconUrlForPage(pageURI, 20),
@@ -207,13 +208,7 @@ add_task(async function test_root_on_different_host() {
// Root favicon for TEST_URL1.
const ICON_URL = "http://places1.test/favicon.ico";
let iconURI = NetUtil.newURI(ICON_URL);
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
- iconURI,
- SMALLPNG_DATA_URI.spec,
- 0,
- systemPrincipal
- );
- await setFaviconForPage(pageURI1, iconURI);
+ await PlacesTestUtils.setFaviconForPage(pageURI1, iconURI, SMALLPNG_DATA_URI);
Assert.equal(await getRootValue(ICON_URL), 1, "Check root == 1");
Assert.equal(
await getFaviconUrlForPage(pageURI1, 16),
@@ -222,13 +217,7 @@ add_task(async function test_root_on_different_host() {
);
// Same favicon for TEST_URL2.
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
- iconURI,
- SMALLPNG_DATA_URI.spec,
- 0,
- systemPrincipal
- );
- await setFaviconForPage(pageURI2, iconURI);
+ await PlacesTestUtils.setFaviconForPage(pageURI2, iconURI, SMALLPNG_DATA_URI);
Assert.equal(await getRootValue(ICON_URL), 1, "Check root == 1");
Assert.equal(
await getFaviconUrlForPage(pageURI2, 16),
diff --git a/toolkit/components/places/tests/favicons/test_setFaviconForPage.js b/toolkit/components/places/tests/favicons/test_setFaviconForPage.js
new file mode 100644
index 0000000000..22364e5410
--- /dev/null
+++ b/toolkit/components/places/tests/favicons/test_setFaviconForPage.js
@@ -0,0 +1,245 @@
+/* Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ * Tests for setFaviconForPage()
+ */
+
+add_task(async function test_validHistoryURI() {
+ let pageURI = uri("http://test1.bar/");
+ await PlacesTestUtils.addVisits(pageURI);
+
+ let favicon = await createFavicon("favicon1.png");
+
+ await doTestSetFaviconForPage({
+ pageURI,
+ faviconURI: favicon.uri,
+ dataURL: await createDataURLForFavicon(favicon),
+ expectedFaviconData: favicon.data,
+ expectedFaviconMimeType: favicon.mimeType,
+ });
+
+ await IOUtils.remove(favicon.file.path);
+ await PlacesUtils.history.clear();
+});
+
+add_task(async function test_overrideDefaultFavicon() {
+ let pageURI = uri("http://test2.bar/");
+ await PlacesTestUtils.addVisits(pageURI);
+
+ let firstFavicon = await createFavicon("favicon2.png");
+ let secondFavicon = await createFavicon("favicon3.png");
+
+ await doTestSetFaviconForPage({
+ pageURI,
+ faviconURI: firstFavicon.uri,
+ dataURL: await createDataURLForFavicon(secondFavicon),
+ expectedFaviconData: secondFavicon.data,
+ expectedFaviconMimeType: secondFavicon.mimeType,
+ });
+
+ await IOUtils.remove(firstFavicon.file.path);
+ await IOUtils.remove(secondFavicon.file.path);
+ await PlacesUtils.history.clear();
+});
+
+add_task(async function test_replaceExisting() {
+ let pageURI = uri("http://test3.bar");
+ await PlacesTestUtils.addVisits(pageURI);
+
+ let firstFavicon = await createFavicon("favicon4.png");
+ let secondFavicon = await createFavicon("favicon5.png");
+
+ await new Promise(resolve => {
+ PlacesUtils.favicons.setAndFetchFaviconForPage(
+ pageURI,
+ firstFavicon.uri,
+ true,
+ PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
+ function test_replaceExisting_firstSet_check(
+ aURI,
+ aDataLen,
+ aData,
+ aMimeType
+ ) {
+ Assert.equal(aMimeType, firstFavicon.mimeType);
+ Assert.ok(compareArrays(aData, firstFavicon.data));
+ checkFaviconDataForPage(
+ pageURI,
+ firstFavicon.mimeType,
+ firstFavicon.data,
+ resolve
+ );
+ },
+ Services.scriptSecurityManager.getSystemPrincipal()
+ );
+ });
+
+ await doTestSetFaviconForPage({
+ pageURI,
+ faviconURI: firstFavicon.uri,
+ dataURL: await createDataURLForFavicon(secondFavicon),
+ expectedFaviconData: secondFavicon.data,
+ expectedFaviconMimeType: secondFavicon.mimeType,
+ });
+
+ await IOUtils.remove(firstFavicon.file.path);
+ await IOUtils.remove(secondFavicon.file.path);
+ await PlacesUtils.history.clear();
+});
+
+add_task(async function test_twiceReplace() {
+ let pageURI = uri("http://test5.bar/");
+ await PlacesTestUtils.addVisits(pageURI);
+
+ let firstFavicon = await createFavicon("favicon9.png");
+ let secondFavicon = await createFavicon("favicon10.png");
+
+ let firstFaviconDataURL = await createDataURLForFavicon(firstFavicon);
+ await new Promise(resolve => {
+ PlacesUtils.favicons.setFaviconForPage(
+ pageURI,
+ firstFavicon.uri,
+ firstFaviconDataURL,
+ null,
+ resolve
+ );
+ });
+
+ await doTestSetFaviconForPage({
+ pageURI,
+ faviconURI: firstFavicon.uri,
+ dataURL: await createDataURLForFavicon(secondFavicon),
+ expectedFaviconData: secondFavicon.data,
+ expectedFaviconMimeType: secondFavicon.mimeType,
+ });
+
+ await IOUtils.remove(firstFavicon.file.path);
+ await IOUtils.remove(secondFavicon.file.path);
+ await PlacesUtils.history.clear();
+});
+
+add_task(async function test_userpass() {
+ let pageURI = uri("http://user:pass@test1.bar/");
+ await PlacesTestUtils.addVisits(pageURI);
+
+ let favicon = await createFavicon("favicon1.png");
+ let faviconURI = uri("http://user:pass@test1.bar/favicon1.png");
+
+ await doTestSetFaviconForPage({
+ pageURI,
+ faviconURI,
+ dataURL: await createDataURLForFavicon(favicon),
+ expectedFaviconData: favicon.data,
+ expectedFaviconMimeType: favicon.mimeType,
+ });
+
+ await IOUtils.remove(favicon.file.path);
+ await PlacesUtils.history.clear();
+});
+
+add_task(async function test_svg() {
+ let pageURI = uri("http://example.com/");
+ await PlacesTestUtils.addVisits(pageURI);
+
+ const svgContent = "<svg><rect width='1px' height='1px%'/></svg>";
+
+ await doTestSetFaviconForPage({
+ pageURI,
+ faviconURI: uri("http://example.com/favicon.svg"),
+ dataURL: uri(`data:image/svg+xml;utf8,${svgContent}`),
+ expectedFaviconData: Array.from(new TextEncoder().encode(svgContent)),
+ expectedFaviconMimeType: "image/svg+xml",
+ });
+
+ await PlacesUtils.history.clear();
+});
+
+add_task(async function test_invalidPageURI() {
+ await PlacesTestUtils.addVisits(uri("http://example.com/"));
+ let favicon = await createFavicon("favicon-invalidPageURI.png");
+
+ for (let invalidURI of [null, "", "http://example.com"]) {
+ try {
+ info(`Invalid page URI test for [${invalidURI}]`);
+ PlacesUtils.favicons.setFaviconForPage(
+ invalidURI,
+ favicon.uri,
+ await createDataURLForFavicon(favicon)
+ );
+ Assert.ok(false, "Error should happened");
+ } catch (e) {
+ Assert.ok(true, `Expected error happend [${e.message}]`);
+ }
+ }
+});
+
+add_task(async function test_invalidFaviconURI() {
+ let pageURI = uri("http://example.com/");
+ await PlacesTestUtils.addVisits(pageURI);
+ let favicon = await createFavicon("favicon-invalidFaviconURI.png");
+
+ for (let invalidURI of [null, "", favicon.uri.spec]) {
+ try {
+ info(`Invalid favicon URI test for [${invalidURI}]`);
+ PlacesUtils.favicons.setFaviconForPage(
+ pageURI,
+ invalidURI,
+ await createDataURLForFavicon(favicon)
+ );
+ Assert.ok(false, "Error should happened");
+ } catch (e) {
+ Assert.ok(true, `Expected error happend [${e.message}]`);
+ }
+ }
+});
+
+add_task(async function test_invalidFaviconDataURI() {
+ let pageURI = uri("http://example.com/");
+ await PlacesTestUtils.addVisits(pageURI);
+ let favicon = createFavicon("favicon-invalidFaviconDataURI.png");
+
+ for (let invalidURI of [
+ null,
+ "",
+ "data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==",
+ ]) {
+ try {
+ info(`Invalid favicon data URI test for [${invalidURI}]`);
+ PlacesUtils.favicons.setFaviconForPage(pageURI, favicon.uri, invalidURI);
+ Assert.ok(false, "Error should happened");
+ } catch (e) {
+ Assert.ok(true, `Expected error happend [${e.message}]`);
+ }
+ }
+});
+
+async function doTestSetFaviconForPage({
+ pageURI,
+ faviconURI,
+ dataURL,
+ expectedFaviconData,
+ expectedFaviconMimeType,
+}) {
+ let result = await new Promise(resolve => {
+ PlacesUtils.favicons.setFaviconForPage(
+ pageURI,
+ faviconURI,
+ dataURL,
+ null,
+ resolve
+ );
+ });
+
+ info("Check the result of setFaviconForPage");
+ Assert.equal(result, 0);
+
+ await new Promise(resolve => {
+ checkFaviconDataForPage(
+ pageURI,
+ expectedFaviconMimeType,
+ expectedFaviconData,
+ resolve
+ );
+ });
+}
diff --git a/toolkit/components/places/tests/favicons/xpcshell.toml b/toolkit/components/places/tests/favicons/xpcshell.toml
index 997aa48e0b..2716e72fda 100644
--- a/toolkit/components/places/tests/favicons/xpcshell.toml
+++ b/toolkit/components/places/tests/favicons/xpcshell.toml
@@ -57,10 +57,6 @@ support-files = [
["test_query_result_favicon_changed_on_child.js"]
-["test_replaceFaviconData.js"]
-
-["test_replaceFaviconDataFromDataURL.js"]
-
["test_root_icons.js"]
["test_setAndFetchFaviconForPage.js"]
@@ -69,4 +65,6 @@ support-files = [
["test_setAndFetchFaviconForPage_redirects.js"]
+["test_setFaviconForPage.js"]
+
["test_svg_favicon.js"]
diff --git a/toolkit/components/places/tests/gtest/places_test_harness_tail.h b/toolkit/components/places/tests/gtest/places_test_harness_tail.h
index 0464d14e0d..27de44eaa9 100644
--- a/toolkit/components/places/tests/gtest/places_test_harness_tail.h
+++ b/toolkit/components/places/tests/gtest/places_test_harness_tail.h
@@ -20,7 +20,7 @@ class RunNextTest : public mozilla::Runnable {
public:
RunNextTest() : mozilla::Runnable("RunNextTest") {}
NS_IMETHOD Run() override {
- NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
+ MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Not running on the main thread?");
if (gTestsIndex < int(mozilla::ArrayLength(gTests))) {
do_test_pending();
Test& test = gTests[gTestsIndex++];
@@ -47,7 +47,7 @@ void run_next_test() {
int gPendingTests = 0;
void do_test_pending() {
- NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
+ MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Not running on the main thread?");
if (kDebugRunNextTest) {
printf_stderr("do_test_pending()\n");
MozWalkTheStack(stderr);
@@ -56,8 +56,8 @@ void do_test_pending() {
}
void do_test_finished() {
- NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
- NS_ASSERTION(gPendingTests > 0, "Invalid pending test count!");
+ MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Not running on the main thread?");
+ MOZ_RELEASE_ASSERT(gPendingTests > 0, "Invalid pending test count!");
gPendingTests--;
}
diff --git a/toolkit/components/places/tests/head_common.js b/toolkit/components/places/tests/head_common.js
index d7a465786e..22d89db139 100644
--- a/toolkit/components/places/tests/head_common.js
+++ b/toolkit/components/places/tests/head_common.js
@@ -169,7 +169,6 @@ function readFileData(aFile) {
}
return bytes;
}
-
/**
* Reads the data from the named file, verifying the expected file length.
*
@@ -187,6 +186,42 @@ function readFileOfLength(aFileName, aExpectedLength) {
}
/**
+ * Reads the data from the specified nsIFile, then returns it as data URL.
+ *
+ * @param file
+ * The nsIFile to read from.
+ * @param mimeType
+ * The mime type of the file content.
+ * @return Promise that retunes data URL.
+ */
+async function readFileDataAsDataURL(file, mimeType) {
+ const data = readFileData(file);
+ return fileDataToDataURL(data, mimeType);
+}
+
+/**
+ * Converts the given data to the data URL.
+ *
+ * @param data
+ * The file data.
+ * @param mimeType
+ * The mime type of the file content.
+ * @return Promise that retunes data URL.
+ */
+async function fileDataToDataURL(data, mimeType) {
+ const dataURL = await new Promise(resolve => {
+ const buffer = new Uint8ClampedArray(data);
+ const blob = new Blob([buffer], { type: mimeType });
+ const reader = new FileReader();
+ reader.onload = e => {
+ resolve(e.target.result);
+ };
+ reader.readAsDataURL(blob);
+ });
+ return dataURL;
+}
+
+/**
* Returns the base64-encoded version of the given string. This function is
* similar to window.btoa, but is available to xpcshell tests also.
*
diff --git a/toolkit/components/places/tests/history/test_remove.js b/toolkit/components/places/tests/history/test_remove.js
index c018a996f3..8c469b5930 100644
--- a/toolkit/components/places/tests/history/test_remove.js
+++ b/toolkit/components/places/tests/history/test_remove.js
@@ -292,20 +292,7 @@ add_task(async function test_orphans() {
);
// Also create a root icon.
let faviconURI = Services.io.newURI(uri.spec + "favicon.ico");
- PlacesUtils.favicons.replaceFaviconDataFromDataURL(
- faviconURI,
- SMALLPNG_DATA_URI.spec,
- 0,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
- PlacesUtils.favicons.setAndFetchFaviconForPage(
- uri,
- faviconURI,
- true,
- PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE,
- null,
- Services.scriptSecurityManager.getSystemPrincipal()
- );
+ await PlacesTestUtils.setFaviconForPage(uri, faviconURI, SMALLPNG_DATA_URI);
await PlacesUtils.history.update({
url: uri,
diff --git a/toolkit/components/places/tests/unit/test_PlacesQuery_history.js b/toolkit/components/places/tests/unit/test_PlacesQuery_history.js
index 9546e03730..24a046bcdc 100644
--- a/toolkit/components/places/tests/unit/test_PlacesQuery_history.js
+++ b/toolkit/components/places/tests/unit/test_PlacesQuery_history.js
@@ -3,6 +3,10 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
+const { sinon } = ChromeUtils.importESModule(
+ "resource://testing-common/Sinon.sys.mjs"
+);
+
const { PlacesQuery } = ChromeUtils.importESModule(
"resource://gre/modules/PlacesQuery.sys.mjs"
);
@@ -243,3 +247,32 @@ add_task(async function test_search_visits() {
await PlacesUtils.history.clear();
});
+
+add_task(async function test_search_interrupt() {
+ const { promise, reject } = Promise.withResolvers();
+ const mockDatabase = {
+ executeCached: async (_, { query }) => {
+ if (query === "First Query") {
+ // Simulate a slow-running query which runs long enough to be
+ // interrupted by the next one.
+ await promise;
+ }
+ return [];
+ },
+ interrupt: () => reject("interrupt() was called."),
+ };
+ const stub = sinon
+ .stub(PlacesUtils, "promiseLargeCacheDBConnection")
+ .resolves(mockDatabase);
+
+ const promiseFirstQuery = placesQuery.searchHistory("First Query");
+ const promiseSecondQuery = placesQuery.searchHistory("Second Query");
+ await Assert.rejects(
+ promiseFirstQuery,
+ /interrupt/,
+ "The first query was interrupted."
+ );
+ ok(await promiseSecondQuery, "The second query resolved normally.");
+
+ stub.restore();
+});