From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../places/tests/unit/bookmarks.glue.html | 16 ++ .../places/tests/unit/bookmarks.glue.json | 83 ++++++++++ .../components/places/tests/unit/corruptDB.sqlite | Bin 0 -> 32772 bytes .../components/places/tests/unit/distribution.ini | 30 ++++ .../components/places/tests/unit/head_bookmarks.js | 89 ++++++++++ .../tests/unit/test_PUIU_batchUpdatesForNode.js | 107 ++++++++++++ .../tests/unit/test_PUIU_setCharsetForPage.js | 141 ++++++++++++++++ .../unit/test_PUIU_title_difference_spotter.js | 81 +++++++++ .../tests/unit/test_browserGlue_bookmarkshtml.js | 33 ++++ .../places/tests/unit/test_browserGlue_corrupt.js | 53 ++++++ .../unit/test_browserGlue_corrupt_nobackup.js | 47 ++++++ .../test_browserGlue_corrupt_nobackup_default.js | 50 ++++++ .../tests/unit/test_browserGlue_distribution.js | 143 ++++++++++++++++ .../places/tests/unit/test_browserGlue_migrate.js | 68 ++++++++ .../places/tests/unit/test_browserGlue_prefs.js | 161 ++++++++++++++++++ .../places/tests/unit/test_browserGlue_restore.js | 55 +++++++ .../tests/unit/test_clearHistory_shutdown.js | 183 +++++++++++++++++++++ .../tests/unit/test_interactions_blocklist.js | 67 ++++++++ .../tests/unit/test_invalid_defaultLocation.js | 24 +++ browser/components/places/tests/unit/xpcshell.ini | 24 +++ 20 files changed, 1455 insertions(+) create mode 100644 browser/components/places/tests/unit/bookmarks.glue.html create mode 100644 browser/components/places/tests/unit/bookmarks.glue.json create mode 100644 browser/components/places/tests/unit/corruptDB.sqlite create mode 100644 browser/components/places/tests/unit/distribution.ini create mode 100644 browser/components/places/tests/unit/head_bookmarks.js create mode 100644 browser/components/places/tests/unit/test_PUIU_batchUpdatesForNode.js create mode 100644 browser/components/places/tests/unit/test_PUIU_setCharsetForPage.js create mode 100644 browser/components/places/tests/unit/test_PUIU_title_difference_spotter.js create mode 100644 browser/components/places/tests/unit/test_browserGlue_bookmarkshtml.js create mode 100644 browser/components/places/tests/unit/test_browserGlue_corrupt.js create mode 100644 browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js create mode 100644 browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js create mode 100644 browser/components/places/tests/unit/test_browserGlue_distribution.js create mode 100644 browser/components/places/tests/unit/test_browserGlue_migrate.js create mode 100644 browser/components/places/tests/unit/test_browserGlue_prefs.js create mode 100644 browser/components/places/tests/unit/test_browserGlue_restore.js create mode 100644 browser/components/places/tests/unit/test_clearHistory_shutdown.js create mode 100644 browser/components/places/tests/unit/test_interactions_blocklist.js create mode 100644 browser/components/places/tests/unit/test_invalid_defaultLocation.js create mode 100644 browser/components/places/tests/unit/xpcshell.ini (limited to 'browser/components/places/tests/unit') diff --git a/browser/components/places/tests/unit/bookmarks.glue.html b/browser/components/places/tests/unit/bookmarks.glue.html new file mode 100644 index 0000000000..07b22e9b3f --- /dev/null +++ b/browser/components/places/tests/unit/bookmarks.glue.html @@ -0,0 +1,16 @@ + + + +Bookmarks +

Bookmarks Menu

+ +

+

example +

Bookmarks Toolbar

+
Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar +

+

example +

+

diff --git a/browser/components/places/tests/unit/bookmarks.glue.json b/browser/components/places/tests/unit/bookmarks.glue.json new file mode 100644 index 0000000000..069f605d29 --- /dev/null +++ b/browser/components/places/tests/unit/bookmarks.glue.json @@ -0,0 +1,83 @@ +{ + "title": "", + "id": 1, + "dateAdded": 1233157910552624, + "lastModified": 1233157955206833, + "type": "text/x-moz-place-container", + "root": "placesRoot", + "children": [ + { + "title": "Bookmarks Menu", + "id": 2, + "parent": 1, + "dateAdded": 1233157910552624, + "lastModified": 1233157993171424, + "type": "text/x-moz-place-container", + "root": "bookmarksMenuFolder", + "children": [ + { + "title": "examplejson", + "id": 27, + "parent": 2, + "dateAdded": 1233157972101126, + "lastModified": 1233157984999673, + "type": "text/x-moz-place", + "uri": "http://example.com/" + } + ] + }, + { + "index": 1, + "title": "Bookmarks Toolbar", + "id": 3, + "parent": 1, + "dateAdded": 1233157910552624, + "lastModified": 1233157972101126, + "annos": [ + { + "name": "bookmarkProperties/description", + "flags": 0, + "expires": 4, + "mimeType": null, + "type": 3, + "value": "Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar" + } + ], + "type": "text/x-moz-place-container", + "root": "toolbarFolder", + "children": [ + { + "title": "examplejson", + "id": 26, + "parent": 3, + "dateAdded": 1233157972101126, + "lastModified": 1233157984999673, + "type": "text/x-moz-place", + "uri": "http://example.com/" + } + ] + }, + { + "index": 2, + "title": "Tags", + "id": 4, + "parent": 1, + "dateAdded": 1233157910552624, + "lastModified": 1233157910582667, + "type": "text/x-moz-place-container", + "root": "tagsFolder", + "children": [] + }, + { + "index": 3, + "title": "Other Bookmarks", + "id": 5, + "parent": 1, + "dateAdded": 1233157910552624, + "lastModified": 1233157911033315, + "type": "text/x-moz-place-container", + "root": "unfiledBookmarksFolder", + "children": [] + } + ] +} diff --git a/browser/components/places/tests/unit/corruptDB.sqlite b/browser/components/places/tests/unit/corruptDB.sqlite new file mode 100644 index 0000000000..b234246cac Binary files /dev/null and b/browser/components/places/tests/unit/corruptDB.sqlite differ diff --git a/browser/components/places/tests/unit/distribution.ini b/browser/components/places/tests/unit/distribution.ini new file mode 100644 index 0000000000..a25c40fed3 --- /dev/null +++ b/browser/components/places/tests/unit/distribution.ini @@ -0,0 +1,30 @@ +# Distribution Configuration File +# Bug 516444 demo + +[Global] +id=516444 +version=1.0 +about=Test distribution file + +[BookmarksToolbar] +item.1.title=Toolbar Link Before +item.1.link=https://example.org/toolbar/before/ +item.1.icon=https://example.org/favicon.png +item.1.iconData=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg== +item.2.type=default +item.3.type=folder +item.3.title=Toolbar Folder After +item.3.folderId=1 + +[BookmarksMenu] +item.1.title=Menu Link Before +item.1.link=https://example.org/menu/before/ +item.1.icon=https://example.org/favicon.png +item.1.iconData=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg== +item.2.type=default +item.3.title=Menu Link After +item.3.link=https://example.org/menu/after/ + +[BookmarksFolder-1] +item.1.title=Toolbar Link Folder +item.1.link=https://example.org/toolbar/folder/ diff --git a/browser/components/places/tests/unit/head_bookmarks.js b/browser/components/places/tests/unit/head_bookmarks.js new file mode 100644 index 0000000000..8aabfb3832 --- /dev/null +++ b/browser/components/places/tests/unit/head_bookmarks.js @@ -0,0 +1,89 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Import common head. +/* import-globals-from ../../../../../toolkit/components/places/tests/head_common.js */ +var commonFile = do_get_file( + "../../../../../toolkit/components/places/tests/head_common.js", + false +); +if (commonFile) { + let uri = Services.io.newFileURI(commonFile); + Services.scriptloader.loadSubScript(uri.spec, this); +} + +// Put any other stuff relative to this test folder below. + +ChromeUtils.defineESModuleGetters(this, { + PlacesUIUtils: "resource:///modules/PlacesUIUtils.sys.mjs", +}); + +// Needed by some test that relies on having an app registered. +const { updateAppInfo } = ChromeUtils.importESModule( + "resource://testing-common/AppInfo.sys.mjs" +); +updateAppInfo({ + name: "PlacesTest", + ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}", + version: "1", + platformVersion: "", +}); + +// Default bookmarks constants. +const DEFAULT_BOOKMARKS_ON_TOOLBAR = 1; +const DEFAULT_BOOKMARKS_ON_MENU = 1; + +function checkItemHasAnnotation(guid, name) { + return PlacesUtils.promiseItemId(guid).then(id => { + let hasAnnotation = PlacesUtils.annotations.itemHasAnnotation(id, name); + Assert.ok(hasAnnotation, `Expected annotation ${name}`); + }); +} + +var createCorruptDB = async function () { + let dbPath = PathUtils.join(PathUtils.profileDir, "places.sqlite"); + await IOUtils.remove(dbPath); + + // Create a corrupt database. + let src = PathUtils.join(do_get_cwd().path, "corruptDB.sqlite"); + await IOUtils.copy(src, dbPath); + + // Check there's a DB now. + Assert.ok(await IOUtils.exists(dbPath), "should have a DB now"); +}; + +const SINGLE_TRY_TIMEOUT = 100; +const NUMBER_OF_TRIES = 30; + +/** + * Similar to waitForConditionPromise, but poll for an asynchronous value + * every SINGLE_TRY_TIMEOUT ms, for no more than tryCount times. + * + * @param {Function} promiseFn + * A function to generate a promise, which resolves to the expected + * asynchronous value. + * @param {msg} timeoutMsg + * The reason to reject the returned promise with. + * @param {number} [tryCount] + * Maximum times to try before rejecting the returned promise with + * timeoutMsg, defaults to NUMBER_OF_TRIES. + * @returns {Promise} to the asynchronous value being polled. + * @throws if the asynchronous value is not available after tryCount attempts. + */ +var waitForResolvedPromise = async function ( + promiseFn, + timeoutMsg, + tryCount = NUMBER_OF_TRIES +) { + let tries = 0; + do { + try { + let value = await promiseFn(); + return value; + } catch (ex) {} + await new Promise(resolve => do_timeout(SINGLE_TRY_TIMEOUT, resolve)); + } while (++tries <= tryCount); + throw new Error(timeoutMsg); +}; diff --git a/browser/components/places/tests/unit/test_PUIU_batchUpdatesForNode.js b/browser/components/places/tests/unit/test_PUIU_batchUpdatesForNode.js new file mode 100644 index 0000000000..58b68d7574 --- /dev/null +++ b/browser/components/places/tests/unit/test_PUIU_batchUpdatesForNode.js @@ -0,0 +1,107 @@ +const { sinon } = ChromeUtils.importESModule( + "resource://testing-common/Sinon.sys.mjs" +); + +/* eslint-disable mozilla/use-chromeutils-generateqi */ + +add_task(async function test_no_result_node() { + let functionSpy = sinon.stub().returns(Promise.resolve()); + + await PlacesUIUtils.batchUpdatesForNode(null, 1, functionSpy); + + Assert.ok( + functionSpy.calledOnce, + "Passing a null result node should still call the wrapped function" + ); +}); + +add_task(async function test_under_batch_threshold() { + let functionSpy = sinon.stub().returns(Promise.resolve()); + let resultNode = { + QueryInterface() { + return this; + }, + onBeginUpdateBatch: sinon.spy(), + onEndUpdateBatch: sinon.spy(), + }; + + await PlacesUIUtils.batchUpdatesForNode(resultNode, 1, functionSpy); + + Assert.ok(functionSpy.calledOnce, "Wrapped function should be called once"); + Assert.ok( + resultNode.onBeginUpdateBatch.notCalled, + "onBeginUpdateBatch should not have been called" + ); + Assert.ok( + resultNode.onEndUpdateBatch.notCalled, + "onEndUpdateBatch should not have been called" + ); +}); + +add_task(async function test_over_batch_threshold() { + let functionSpy = sinon.stub().callsFake(() => { + Assert.ok( + resultNode.onBeginUpdateBatch.calledOnce, + "onBeginUpdateBatch should have been called before the function" + ); + Assert.ok( + resultNode.onEndUpdateBatch.notCalled, + "onEndUpdateBatch should not have been called before the function" + ); + + return Promise.resolve(); + }); + let resultNode = { + QueryInterface() { + return this; + }, + onBeginUpdateBatch: sinon.spy(), + onEndUpdateBatch: sinon.spy(), + }; + + await PlacesUIUtils.batchUpdatesForNode(resultNode, 100, functionSpy); + + Assert.ok(functionSpy.calledOnce, "Wrapped function should be called once"); + Assert.ok( + resultNode.onBeginUpdateBatch.calledOnce, + "onBeginUpdateBatch should have been called" + ); + Assert.ok( + resultNode.onEndUpdateBatch.calledOnce, + "onEndUpdateBatch should have been called" + ); +}); + +add_task(async function test_wrapped_function_throws() { + let error = new Error("Failed!"); + let functionSpy = sinon.stub().throws(error); + let resultNode = { + QueryInterface() { + return this; + }, + onBeginUpdateBatch: sinon.spy(), + onEndUpdateBatch: sinon.spy(), + }; + + let raisedError; + try { + await PlacesUIUtils.batchUpdatesForNode(resultNode, 100, functionSpy); + } catch (ex) { + raisedError = ex; + } + + Assert.ok(functionSpy.calledOnce, "Wrapped function should be called once"); + Assert.ok( + resultNode.onBeginUpdateBatch.calledOnce, + "onBeginUpdateBatch should have been called" + ); + Assert.ok( + resultNode.onEndUpdateBatch.calledOnce, + "onEndUpdateBatch should have been called" + ); + Assert.equal( + raisedError, + error, + "batchUpdatesForNode should have raised the error from the wrapped function" + ); +}); diff --git a/browser/components/places/tests/unit/test_PUIU_setCharsetForPage.js b/browser/components/places/tests/unit/test_PUIU_setCharsetForPage.js new file mode 100644 index 0000000000..db213971e9 --- /dev/null +++ b/browser/components/places/tests/unit/test_PUIU_setCharsetForPage.js @@ -0,0 +1,141 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const { PrivateBrowsingUtils } = ChromeUtils.importESModule( + "resource://gre/modules/PrivateBrowsingUtils.sys.mjs" +); + +const UTF8 = "UTF-8"; +const UTF16 = "UTF-16"; + +const TEST_URI = "http://foo.com"; +const TEST_BOOKMARKED_URI = "http://bar.com"; + +add_task(function setup() { + let savedIsWindowPrivateFunc = PrivateBrowsingUtils.isWindowPrivate; + PrivateBrowsingUtils.isWindowPrivate = () => false; + + registerCleanupFunction(() => { + PrivateBrowsingUtils.isWindowPrivate = savedIsWindowPrivateFunc; + }); +}); + +add_task(async function test_simple_add() { + // add pages to history + await PlacesTestUtils.addVisits(TEST_URI); + await PlacesTestUtils.addVisits(TEST_BOOKMARKED_URI); + + // create bookmarks on TEST_BOOKMARKED_URI + await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.unfiledGuid, + url: TEST_BOOKMARKED_URI, + title: TEST_BOOKMARKED_URI.spec, + }); + await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + url: TEST_BOOKMARKED_URI, + title: TEST_BOOKMARKED_URI.spec, + }); + + // set charset on not-bookmarked page + await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {}); + // set charset on bookmarked page + await PlacesUIUtils.setCharsetForPage(TEST_BOOKMARKED_URI, UTF16, {}); + + let pageInfo = await PlacesUtils.history.fetch(TEST_URI, { + includeAnnotations: true, + }); + Assert.equal( + pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), + UTF16, + "Should return correct charset for a not-bookmarked page" + ); + + pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, { + includeAnnotations: true, + }); + Assert.equal( + pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), + UTF16, + "Should return correct charset for a bookmarked page" + ); + + await PlacesUtils.history.clear(); + + pageInfo = await PlacesUtils.history.fetch(TEST_URI, { + includeAnnotations: true, + }); + Assert.ok( + !pageInfo, + "Should not return pageInfo for a page after history cleared" + ); + + pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, { + includeAnnotations: true, + }); + Assert.equal( + pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), + UTF16, + "Charset should still be set for a bookmarked page after history clear" + ); + + await PlacesUIUtils.setCharsetForPage(TEST_BOOKMARKED_URI, ""); + pageInfo = await PlacesUtils.history.fetch(TEST_BOOKMARKED_URI, { + includeAnnotations: true, + }); + Assert.strictEqual( + pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), + undefined, + "Should not have a charset after it has been removed from the page" + ); +}); + +add_task(async function test_utf8_clears_saved_anno() { + await PlacesUtils.history.clear(); + await PlacesTestUtils.addVisits(TEST_URI); + + // set charset on bookmarked page + await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {}); + + let pageInfo = await PlacesUtils.history.fetch(TEST_URI, { + includeAnnotations: true, + }); + Assert.equal( + pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), + UTF16, + "Should return correct charset for a not-bookmarked page" + ); + + // Now set the bookmark to a UTF-8 charset. + await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF8, {}); + + pageInfo = await PlacesUtils.history.fetch(TEST_URI, { + includeAnnotations: true, + }); + Assert.strictEqual( + pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), + undefined, + "Should have removed the charset for a UTF-8 page." + ); +}); + +add_task(async function test_private_browsing_not_saved() { + await PlacesUtils.history.clear(); + await PlacesTestUtils.addVisits(TEST_URI); + + // set charset on bookmarked page, but pretend this is a private browsing window. + PrivateBrowsingUtils.isWindowPrivate = () => true; + await PlacesUIUtils.setCharsetForPage(TEST_URI, UTF16, {}); + + let pageInfo = await PlacesUtils.history.fetch(TEST_URI, { + includeAnnotations: true, + }); + Assert.strictEqual( + pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), + undefined, + "Should not have set the charset in a private browsing window." + ); +}); diff --git a/browser/components/places/tests/unit/test_PUIU_title_difference_spotter.js b/browser/components/places/tests/unit/test_PUIU_title_difference_spotter.js new file mode 100644 index 0000000000..aaa4db6bb2 --- /dev/null +++ b/browser/components/places/tests/unit/test_PUIU_title_difference_spotter.js @@ -0,0 +1,81 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests the difference indication for titles. + */ + +const TESTS = [ + { + title: null, + expected: undefined, + }, + { + title: "Short title", + expected: undefined, + }, + { + title: "Short title2", + expected: undefined, + }, + { + title: "Long title same as another", + expected: undefined, + }, + { + title: "Long title same as another", + expected: undefined, + }, + { + title: "Long title with difference at the end 1", + expected: 38, + }, + { + title: "Long title with difference at the end 2", + expected: 38, + }, + { + title: "A long title with difference 123456 in the middle.", + expected: 30, + }, + { + title: "A long title with difference 135246 in the middle.", + expected: 30, + }, + { + title: + "Some long titles with variable 12345678 differences to 13572468 other titles", + expected: 32, + }, + { + title: + "Some long titles with variable 12345678 differences to 15263748 other titles", + expected: 32, + }, + { + title: + "Some long titles with variable 15263748 differences to 12345678 other titles", + expected: 32, + }, + { + title: "One long title which will be shorter than the other one", + expected: 40, + }, + { + title: + "One long title which will be shorter that the other one (not this one)", + expected: 40, + }, +]; + +add_task(async function test_difference_finding() { + PlacesUIUtils.insertTitleStartDiffs(TESTS); + + for (let result of TESTS) { + Assert.equal( + result.titleDifferentIndex, + result.expected, + `Should have returned the correct index for "${result.title}"` + ); + } +}); diff --git a/browser/components/places/tests/unit/test_browserGlue_bookmarkshtml.js b/browser/components/places/tests/unit/test_browserGlue_bookmarkshtml.js new file mode 100644 index 0000000000..65a038487a --- /dev/null +++ b/browser/components/places/tests/unit/test_browserGlue_bookmarkshtml.js @@ -0,0 +1,33 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Tests that nsBrowserGlue correctly exports bookmarks.html at shutdown if + * browser.bookmarks.autoExportHTML is set to true. + */ + +add_task(async function () { + remove_bookmarks_html(); + + Services.prefs.setBoolPref("browser.bookmarks.autoExportHTML", true); + registerCleanupFunction(() => + Services.prefs.clearUserPref("browser.bookmarks.autoExportHTML") + ); + + // Initialize nsBrowserGlue before Places. + Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports); + + // Initialize Places through the History Service. + Assert.equal( + PlacesUtils.history.databaseStatus, + PlacesUtils.history.DATABASE_STATUS_CREATE + ); + + Services.obs.addObserver(function observer() { + Services.obs.removeObserver(observer, "profile-before-change"); + check_bookmarks_html(); + }, "profile-before-change"); +}); diff --git a/browser/components/places/tests/unit/test_browserGlue_corrupt.js b/browser/components/places/tests/unit/test_browserGlue_corrupt.js new file mode 100644 index 0000000000..0514b06bbc --- /dev/null +++ b/browser/components/places/tests/unit/test_browserGlue_corrupt.js @@ -0,0 +1,53 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Tests that nsBrowserGlue correctly restores bookmarks from a JSON backup if + * database is corrupt and one backup is available. + */ + +function run_test() { + // Create our bookmarks.html from bookmarks.glue.html. + create_bookmarks_html("bookmarks.glue.html"); + + remove_all_JSON_backups(); + + // Create our JSON backup from bookmarks.glue.json. + create_JSON_backup("bookmarks.glue.json"); + + run_next_test(); +} + +registerCleanupFunction(function () { + remove_bookmarks_html(); + remove_all_JSON_backups(); + return PlacesUtils.bookmarks.eraseEverything(); +}); + +add_task(async function test_main() { + // Create a corrupt database. + await createCorruptDB(); + + // Initialize nsBrowserGlue before Places. + Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports); + + // Check the database was corrupt. + // nsBrowserGlue uses databaseStatus to manage initialization. + Assert.equal( + PlacesUtils.history.databaseStatus, + PlacesUtils.history.DATABASE_STATUS_CORRUPT + ); + + // The test will continue once restore has finished. + await promiseTopicObserved("places-browser-init-complete"); + + // Check that JSON backup has been restored. + let bm = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + }); + Assert.equal(bm.title, "examplejson"); +}); diff --git a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js new file mode 100644 index 0000000000..a0bc93c74c --- /dev/null +++ b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js @@ -0,0 +1,47 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Tests that nsBrowserGlue correctly imports from bookmarks.html if database + * is corrupt but a JSON backup is not available. + */ + +function run_test() { + // Create our bookmarks.html from bookmarks.glue.html. + create_bookmarks_html("bookmarks.glue.html"); + + // Remove JSON backup from profile. + remove_all_JSON_backups(); + + run_next_test(); +} + +registerCleanupFunction(remove_bookmarks_html); + +add_task(async function () { + // Create a corrupt database. + await createCorruptDB(); + + // Initialize nsBrowserGlue before Places. + Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports); + + // Check the database was corrupt. + // nsBrowserGlue uses databaseStatus to manage initialization. + Assert.equal( + PlacesUtils.history.databaseStatus, + PlacesUtils.history.DATABASE_STATUS_CORRUPT + ); + + // The test will continue once import has finished. + await promiseTopicObserved("places-browser-init-complete"); + + // Check that bookmarks html has been restored. + let bm = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + }); + Assert.equal(bm.title, "example"); +}); diff --git a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js new file mode 100644 index 0000000000..031d82d9e2 --- /dev/null +++ b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js @@ -0,0 +1,50 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Tests that nsBrowserGlue correctly restores default bookmarks if database is + * corrupt, nor a JSON backup nor bookmarks.html are available. + */ + +function run_test() { + // Remove bookmarks.html from profile. + remove_bookmarks_html(); + + // Remove JSON backup from profile. + remove_all_JSON_backups(); + + run_next_test(); +} + +add_task(async function () { + // Create a corrupt database. + await createCorruptDB(); + + // Initialize nsBrowserGlue before Places. + Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports); + + // Check the database was corrupt. + // nsBrowserGlue uses databaseStatus to manage initialization. + Assert.equal( + PlacesUtils.history.databaseStatus, + PlacesUtils.history.DATABASE_STATUS_CORRUPT + ); + + // The test will continue once import has finished. + await promiseTopicObserved("places-browser-init-complete"); + + // Check that default bookmarks have been restored. + let bm = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + }); + + // Bug 1283076: Nightly bookmark points to Get Involved page, not Getting Started one + let chanTitle = AppConstants.NIGHTLY_BUILD + ? "Get Involved" + : "Getting Started"; + Assert.equal(bm.title, chanTitle); +}); diff --git a/browser/components/places/tests/unit/test_browserGlue_distribution.js b/browser/components/places/tests/unit/test_browserGlue_distribution.js new file mode 100644 index 0000000000..e2bee06bcb --- /dev/null +++ b/browser/components/places/tests/unit/test_browserGlue_distribution.js @@ -0,0 +1,143 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that nsBrowserGlue correctly imports bookmarks from distribution.ini. + */ + +const PREF_BMPROCESSED = "distribution.516444.bookmarksProcessed"; +const PREF_DISTRIBUTION_ID = "distribution.id"; + +const TOPICDATA_DISTRIBUTION_CUSTOMIZATION = "force-distribution-customization"; +const TOPIC_CUSTOMIZATION_COMPLETE = "distribution-customization-complete"; +const TOPIC_BROWSERGLUE_TEST = "browser-glue-test"; + +function run_test() { + // Set special pref to load distribution.ini from the profile folder. + Services.prefs.setBoolPref("distribution.testing.loadFromProfile", true); + + // Copy distribution.ini file to the profile dir. + let distroDir = gProfD.clone(); + distroDir.leafName = "distribution"; + let iniFile = distroDir.clone(); + iniFile.append("distribution.ini"); + if (iniFile.exists()) { + iniFile.remove(false); + print("distribution.ini already exists, did some test forget to cleanup?"); + } + + let testDistributionFile = gTestDir.clone(); + testDistributionFile.append("distribution.ini"); + testDistributionFile.copyTo(distroDir, "distribution.ini"); + Assert.ok(testDistributionFile.exists()); + + run_next_test(); +} + +registerCleanupFunction(function () { + // Remove the distribution file, even if the test failed, otherwise all + // next tests will import it. + let iniFile = gProfD.clone(); + iniFile.leafName = "distribution"; + iniFile.append("distribution.ini"); + if (iniFile.exists()) { + iniFile.remove(false); + } + Assert.ok(!iniFile.exists()); +}); + +add_task(async function () { + let { DistributionCustomizer } = ChromeUtils.import( + "resource:///modules/distribution.js" + ); + let distribution = new DistributionCustomizer(); + + let glue = Cc["@mozilla.org/browser/browserglue;1"].getService( + Ci.nsIObserver + ); + // Initialize Places through the History Service and check that a new + // database has been created. + Assert.equal( + PlacesUtils.history.databaseStatus, + PlacesUtils.history.DATABASE_STATUS_CREATE + ); + // Force distribution. + glue.observe( + null, + TOPIC_BROWSERGLUE_TEST, + TOPICDATA_DISTRIBUTION_CUSTOMIZATION + ); + + // Test will continue on customization complete notification. + await promiseTopicObserved(TOPIC_CUSTOMIZATION_COMPLETE); + + // Check the custom bookmarks exist on menu. + let menuItem = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.menuGuid, + index: 0, + }); + Assert.equal(menuItem.title, "Menu Link Before"); + Assert.ok( + menuItem.guid.startsWith(distribution.BOOKMARK_GUID_PREFIX), + "Guid of this bookmark has expected prefix" + ); + + menuItem = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.menuGuid, + index: 1 + DEFAULT_BOOKMARKS_ON_MENU, + }); + Assert.equal(menuItem.title, "Menu Link After"); + + // Check no favicon exists for this bookmark + await Assert.rejects( + waitForResolvedPromise( + () => { + return PlacesUtils.promiseFaviconData(menuItem.url.href); + }, + "Favicon not found", + 10 + ), + /Favicon\snot\sfound/, + "Favicon not found" + ); + + // Check the custom bookmarks exist on toolbar. + let toolbarItem = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + }); + Assert.equal(toolbarItem.title, "Toolbar Link Before"); + + // Check the custom favicon exist for this bookmark + let faviconItem = await waitForResolvedPromise( + () => { + return PlacesUtils.promiseFaviconData(toolbarItem.url.href); + }, + "Favicon not found", + 10 + ); + Assert.equal(faviconItem.uri.spec, "https://example.org/favicon.png"); + Assert.greater(faviconItem.dataLen, 0); + Assert.equal(faviconItem.mimeType, "image/png"); + + let base64Icon = + "data:image/png;base64," + + base64EncodeString(String.fromCharCode.apply(String, faviconItem.data)); + Assert.equal(base64Icon, SMALLPNG_DATA_URI.spec); + + toolbarItem = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 1 + DEFAULT_BOOKMARKS_ON_TOOLBAR, + }); + Assert.equal(toolbarItem.title, "Toolbar Folder After"); + Assert.ok( + toolbarItem.guid.startsWith(distribution.FOLDER_GUID_PREFIX), + "Guid of this folder has expected prefix" + ); + + // Check the bmprocessed pref has been created. + Assert.ok(Services.prefs.getBoolPref(PREF_BMPROCESSED)); + + // Check distribution prefs have been created. + Assert.equal(Services.prefs.getCharPref(PREF_DISTRIBUTION_ID), "516444"); +}); diff --git a/browser/components/places/tests/unit/test_browserGlue_migrate.js b/browser/components/places/tests/unit/test_browserGlue_migrate.js new file mode 100644 index 0000000000..f0f88d2d17 --- /dev/null +++ b/browser/components/places/tests/unit/test_browserGlue_migrate.js @@ -0,0 +1,68 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that nsBrowserGlue does not overwrite bookmarks imported from the + * migrators. They usually run before nsBrowserGlue, so if we find any + * bookmark on init, we should not try to import. + */ + +function run_test() { + // Create our bookmarks.html from bookmarks.glue.html. + create_bookmarks_html("bookmarks.glue.html"); + + // Remove current database file. + clearDB(); + + run_next_test(); +} + +registerCleanupFunction(remove_bookmarks_html); + +add_task(async function test_migrate_bookmarks() { + // Initialize Places through the History Service and check that a new + // database has been created. + Assert.equal( + PlacesUtils.history.databaseStatus, + PlacesUtils.history.DATABASE_STATUS_CREATE + ); + + // A migrator would run before nsBrowserGlue Places initialization, so mimic + // that behavior adding a bookmark and notifying the migration. + let bg = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver); + bg.observe(null, "initial-migration-will-import-default-bookmarks", null); + + await PlacesUtils.bookmarks.insert({ + parentGuid: PlacesUtils.bookmarks.menuGuid, + index: PlacesUtils.bookmarks.DEFAULT_INDEX, + type: PlacesUtils.bookmarks.TYPE_BOOKMARK, + url: "http://mozilla.org/", + title: "migrated", + }); + + let promise = promiseTopicObserved("places-browser-init-complete"); + bg.observe(null, "initial-migration-did-import-default-bookmarks", null); + await promise; + + // Check the created bookmark still exists. + let bm = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.menuGuid, + index: 0, + }); + Assert.equal(bm.title, "migrated"); + + // Check that we have not imported any new bookmark. + Assert.ok( + !(await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.menuGuid, + index: 1, + })) + ); + + Assert.ok( + !(await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + })) + ); +}); diff --git a/browser/components/places/tests/unit/test_browserGlue_prefs.js b/browser/components/places/tests/unit/test_browserGlue_prefs.js new file mode 100644 index 0000000000..af1dc3db0e --- /dev/null +++ b/browser/components/places/tests/unit/test_browserGlue_prefs.js @@ -0,0 +1,161 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that nsBrowserGlue is correctly interpreting the preferences settable + * by the user or by other components. + */ + +const PREF_IMPORT_BOOKMARKS_HTML = "browser.places.importBookmarksHTML"; +const PREF_RESTORE_DEFAULT_BOOKMARKS = + "browser.bookmarks.restore_default_bookmarks"; +const PREF_AUTO_EXPORT_HTML = "browser.bookmarks.autoExportHTML"; + +const TOPIC_BROWSERGLUE_TEST = "browser-glue-test"; +const TOPICDATA_FORCE_PLACES_INIT = "test-force-places-init"; + +var bg = Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIObserver); + +add_task(async function setup() { + // Create our bookmarks.html from bookmarks.glue.html. + create_bookmarks_html("bookmarks.glue.html"); + + remove_all_JSON_backups(); + + // Create our JSON backup from bookmarks.glue.json. + create_JSON_backup("bookmarks.glue.json"); + + registerCleanupFunction(function () { + remove_bookmarks_html(); + remove_all_JSON_backups(); + + return PlacesUtils.bookmarks.eraseEverything(); + }); +}); + +function simulatePlacesInit() { + info("Simulate Places init"); + // Force nsBrowserGlue::_initPlaces(). + bg.observe(null, TOPIC_BROWSERGLUE_TEST, TOPICDATA_FORCE_PLACES_INIT); + return promiseTopicObserved("places-browser-init-complete"); +} + +add_task(async function test_checkPreferences() { + // Initialize Places through the History Service and check that a new + // database has been created. + let promiseComplete = promiseTopicObserved("places-browser-init-complete"); + Assert.equal( + PlacesUtils.history.databaseStatus, + PlacesUtils.history.DATABASE_STATUS_CREATE + ); + await promiseComplete; + + // Ensure preferences status. + Assert.ok(!Services.prefs.getBoolPref(PREF_AUTO_EXPORT_HTML)); + + Assert.throws( + () => Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML), + /NS_ERROR_UNEXPECTED/ + ); + Assert.throws( + () => Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS), + /NS_ERROR_UNEXPECTED/ + ); +}); + +add_task(async function test_import() { + info("Import from bookmarks.html if importBookmarksHTML is true."); + + await PlacesUtils.bookmarks.eraseEverything(); + + // Sanity check: we should not have any bookmark on the toolbar. + Assert.ok( + !(await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + })) + ); + + // Set preferences. + Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true); + + await simulatePlacesInit(); + + // Check bookmarks.html has been imported. + let bm = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + }); + Assert.equal(bm.title, "example"); + + // Check preferences have been reverted. + Assert.ok(!Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML)); +}); + +add_task(async function test_restore() { + info( + "restore from default bookmarks.html if " + + "restore_default_bookmarks is true." + ); + + await PlacesUtils.bookmarks.eraseEverything(); + + // Sanity check: we should not have any bookmark on the toolbar. + Assert.ok( + !(await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + })) + ); + + // Set preferences. + Services.prefs.setBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS, true); + + await simulatePlacesInit(); + + // Check bookmarks.html has been restored. + Assert.ok( + await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + }) + ); + + // Check preferences have been reverted. + Assert.ok(!Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS)); +}); + +add_task(async function test_restore_import() { + info( + "setting both importBookmarksHTML and " + + "restore_default_bookmarks should restore defaults." + ); + + await PlacesUtils.bookmarks.eraseEverything(); + + // Sanity check: we should not have any bookmark on the toolbar. + Assert.ok( + !(await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + })) + ); + + // Set preferences. + Services.prefs.setBoolPref(PREF_IMPORT_BOOKMARKS_HTML, true); + Services.prefs.setBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS, true); + + await simulatePlacesInit(); + + // Check bookmarks.html has been restored. + Assert.ok( + await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + }) + ); + + // Check preferences have been reverted. + Assert.ok(!Services.prefs.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS)); + Assert.ok(!Services.prefs.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML)); +}); diff --git a/browser/components/places/tests/unit/test_browserGlue_restore.js b/browser/components/places/tests/unit/test_browserGlue_restore.js new file mode 100644 index 0000000000..98c8d1d2d6 --- /dev/null +++ b/browser/components/places/tests/unit/test_browserGlue_restore.js @@ -0,0 +1,55 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Tests that nsBrowserGlue correctly restores bookmarks from a JSON backup if + * database has been created and one backup is available. + */ + +function run_test() { + // Create our bookmarks.html from bookmarks.glue.html. + create_bookmarks_html("bookmarks.glue.html"); + + remove_all_JSON_backups(); + + // Create our JSON backup from bookmarks.glue.json. + create_JSON_backup("bookmarks.glue.json"); + + // Remove current database file. + clearDB(); + + run_next_test(); +} + +registerCleanupFunction(function () { + remove_bookmarks_html(); + remove_all_JSON_backups(); + return PlacesUtils.bookmarks.eraseEverything(); +}); + +add_task(async function test_main() { + // Initialize nsBrowserGlue before Places. + Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsISupports); + + // Initialize Places through the History Service. + let hs = Cc["@mozilla.org/browser/nav-history-service;1"].getService( + Ci.nsINavHistoryService + ); + + // Check a new database has been created. + // nsBrowserGlue uses databaseStatus to manage initialization. + Assert.equal(hs.databaseStatus, hs.DATABASE_STATUS_CREATE); + + // The test will continue once restore has finished. + await promiseTopicObserved("places-browser-init-complete"); + + // Check that JSON backup has been restored. + let bm = await PlacesUtils.bookmarks.fetch({ + parentGuid: PlacesUtils.bookmarks.toolbarGuid, + index: 0, + }); + Assert.equal(bm.title, "examplejson"); +}); diff --git a/browser/components/places/tests/unit/test_clearHistory_shutdown.js b/browser/components/places/tests/unit/test_clearHistory_shutdown.js new file mode 100644 index 0000000000..27b432e569 --- /dev/null +++ b/browser/components/places/tests/unit/test_clearHistory_shutdown.js @@ -0,0 +1,183 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Tests that requesting clear history at shutdown will really clear history. + */ + +const URIS = [ + "http://a.example1.com/", + "http://b.example1.com/", + "http://b.example2.com/", + "http://c.example3.com/", +]; + +const FTP_URL = "ftp://localhost/clearHistoryOnShutdown/"; + +const { Sanitizer } = ChromeUtils.importESModule( + "resource:///modules/Sanitizer.sys.mjs" +); + +// Send the profile-after-change notification to the form history component to ensure +// that it has been initialized. +var formHistoryStartup = Cc[ + "@mozilla.org/satchel/form-history-startup;1" +].getService(Ci.nsIObserver); +formHistoryStartup.observe(null, "profile-after-change", null); +ChromeUtils.defineESModuleGetters(this, { + FormHistory: "resource://gre/modules/FormHistory.sys.mjs", +}); + +var timeInMicroseconds = Date.now() * 1000; + +add_task(async function test_execute() { + info("Initialize browserglue before Places"); + + // Avoid default bookmarks import. + let glue = Cc["@mozilla.org/browser/browserglue;1"].getService( + Ci.nsIObserver + ); + glue.observe(null, "initial-migration-will-import-default-bookmarks", null); + Sanitizer.onStartup(); + + Services.prefs.setBoolPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "cache", true); + Services.prefs.setBoolPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "cookies", true); + Services.prefs.setBoolPref( + Sanitizer.PREF_SHUTDOWN_BRANCH + "offlineApps", + true + ); + Services.prefs.setBoolPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "history", true); + Services.prefs.setBoolPref( + Sanitizer.PREF_SHUTDOWN_BRANCH + "downloads", + true + ); + Services.prefs.setBoolPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "cookies", true); + Services.prefs.setBoolPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "formData", true); + Services.prefs.setBoolPref(Sanitizer.PREF_SHUTDOWN_BRANCH + "sessions", true); + Services.prefs.setBoolPref( + Sanitizer.PREF_SHUTDOWN_BRANCH + "siteSettings", + true + ); + + Services.prefs.setBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, true); + + info("Add visits."); + for (let aUrl of URIS) { + await PlacesTestUtils.addVisits({ + uri: uri(aUrl), + visitDate: timeInMicroseconds++, + transition: PlacesUtils.history.TRANSITION_TYPED, + }); + } + info("Add cache."); + await storeCache(FTP_URL, "testData"); + info("Add form history."); + await addFormHistory(); + Assert.equal(await getFormHistoryCount(), 1, "Added form history"); + + info("Simulate and wait shutdown."); + await shutdownPlaces(); + + Assert.equal(await getFormHistoryCount(), 0, "Form history cleared"); + + let stmt = DBConn(true).createStatement( + "SELECT id FROM moz_places WHERE url = :page_url " + ); + + try { + URIS.forEach(function (aUrl) { + stmt.params.page_url = aUrl; + Assert.ok(!stmt.executeStep()); + stmt.reset(); + }); + } finally { + stmt.finalize(); + } + + info("Check cache"); + // Check cache. + await checkCache(FTP_URL); +}); + +function addFormHistory() { + let now = Date.now() * 1000; + return FormHistory.update({ + op: "add", + fieldname: "testfield", + value: "test", + timesUsed: 1, + firstUsed: now, + lastUsed: now, + }); +} + +async function getFormHistoryCount() { + return FormHistory.count({ fieldname: "testfield" }); +} + +function storeCache(aURL, aContent) { + let cache = Services.cache2; + let storage = cache.diskCacheStorage(Services.loadContextInfo.default); + + return new Promise(resolve => { + let storeCacheListener = { + onCacheEntryCheck(entry) { + return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; + }, + + onCacheEntryAvailable(entry, isnew, status) { + Assert.equal(status, Cr.NS_OK); + + entry.setMetaDataElement("servertype", "0"); + var os = entry.openOutputStream(0, -1); + + var written = os.write(aContent, aContent.length); + if (written != aContent.length) { + do_throw( + "os.write has not written all data!\n" + + " Expected: " + + written + + "\n" + + " Actual: " + + aContent.length + + "\n" + ); + } + os.close(); + entry.close(); + resolve(); + }, + }; + + storage.asyncOpenURI( + Services.io.newURI(aURL), + "", + Ci.nsICacheStorage.OPEN_NORMALLY, + storeCacheListener + ); + }); +} + +function checkCache(aURL) { + let cache = Services.cache2; + let storage = cache.diskCacheStorage(Services.loadContextInfo.default); + + return new Promise(resolve => { + let checkCacheListener = { + onCacheEntryAvailable(entry, isnew, status) { + Assert.equal(status, Cr.NS_ERROR_CACHE_KEY_NOT_FOUND); + resolve(); + }, + }; + + storage.asyncOpenURI( + Services.io.newURI(aURL), + "", + Ci.nsICacheStorage.OPEN_READONLY, + checkCacheListener + ); + }); +} diff --git a/browser/components/places/tests/unit/test_interactions_blocklist.js b/browser/components/places/tests/unit/test_interactions_blocklist.js new file mode 100644 index 0000000000..0e81f80af2 --- /dev/null +++ b/browser/components/places/tests/unit/test_interactions_blocklist.js @@ -0,0 +1,67 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that blocked sites are caught by InteractionsBlocklist. + */ + +ChromeUtils.defineESModuleGetters(this, { + InteractionsBlocklist: "resource:///modules/InteractionsBlocklist.sys.mjs", +}); + +let BLOCKED_URLS = [ + "https://www.bing.com/search?q=mozilla", + "https://duckduckgo.com/?q=a+test&kp=1&t=ffab", + "https://www.google.com/search?q=mozilla", + "https://www.google.ca/search?q=test", + "https://mozilla.zoom.us/j/123456789", + "https://yandex.az/search/?text=mozilla", + "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&ch=&tn=baidu&bar=&wd=mozilla&rn=&fenlei=256&oq=&rsv_pq=970f2b8f001757b9&rsv_t=1f5d2V2o80HPdZtZnhodwkc7nZXTvDI1zwdPy%2FAeomnvFFGIrU1F3D9WoK4&rqlang=cn", + "https://accounts.google.com/o/oauth2/v2/auth/identifier/foobar", + "https://auth.mozilla.auth0.com/login/foobar", + "https://accounts.google.com/signin/oauth/consent/foobar", + "https://accounts.google.com/o/oauth2/v2/auth?client_id=ZZZ", + "https://login.microsoftonline.com/common/oauth2/v2.0/authorize/foobar", +]; + +let ALLOWED_URLS = [ + "https://example.com", + "https://zoom.us/pricing", + "https://www.google.ca/maps/place/Toronto,+ON/@43.7181557,-79.5181414,11z/data=!3m1!4b1!4m5!3m4!1s0x89d4cb90d7c63ba5:0x323555502ab4c477!8m2!3d43.653226!4d-79.3831843", + "https://example.com/https://auth.mozilla.auth0.com/login/foobar", +]; + +// Tests that initializing InteractionsBlocklist loads the regexes from the +// customBlocklist pref on initialization. This subtest should always be the +// first one in this file. +add_task(async function blockedOnInit() { + Services.prefs.setStringPref( + "places.interactions.customBlocklist", + '["^(https?:\\\\/\\\\/)?mochi.test"]' + ); + Assert.ok( + InteractionsBlocklist.isUrlBlocklisted("https://mochi.test"), + "mochi.test is blocklisted." + ); + InteractionsBlocklist.removeRegexFromBlocklist("^(https?:\\/\\/)?mochi.test"); + Assert.ok( + !InteractionsBlocklist.isUrlBlocklisted("https://mochi.test"), + "mochi.test is not blocklisted." + ); +}); + +add_task(async function test() { + for (let url of BLOCKED_URLS) { + Assert.ok( + InteractionsBlocklist.isUrlBlocklisted(url), + `${url} is blocklisted.` + ); + } + + for (let url of ALLOWED_URLS) { + Assert.ok( + !InteractionsBlocklist.isUrlBlocklisted(url), + `${url} is not blocklisted.` + ); + } +}); diff --git a/browser/components/places/tests/unit/test_invalid_defaultLocation.js b/browser/components/places/tests/unit/test_invalid_defaultLocation.js new file mode 100644 index 0000000000..e533d051d0 --- /dev/null +++ b/browser/components/places/tests/unit/test_invalid_defaultLocation.js @@ -0,0 +1,24 @@ +/* Any copyright is dedicated to the Public Domain. + * https://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +/** + * Test that if browser.bookmarks.defaultLocation contains an invalid GUID, + * PlacesUIUtils.defaultParentGuid will return a proper default value. + */ + +add_task(async function () { + Services.prefs.setCharPref( + "browser.bookmarks.defaultLocation", + "useOtherBookmarks" + ); + + info( + "Checking that default parent guid was set back to the toolbar because of invalid preferable guid" + ); + Assert.equal( + await PlacesUIUtils.defaultParentGuid, + PlacesUtils.bookmarks.toolbarGuid, + "Default parent guid is a toolbar guid" + ); +}); diff --git a/browser/components/places/tests/unit/xpcshell.ini b/browser/components/places/tests/unit/xpcshell.ini new file mode 100644 index 0000000000..4c0d0f7c92 --- /dev/null +++ b/browser/components/places/tests/unit/xpcshell.ini @@ -0,0 +1,24 @@ +[DEFAULT] +head = head_bookmarks.js +firefox-appdir = browser +skip-if = toolkit == 'android' # bug 1730213 +support-files = + bookmarks.glue.html + bookmarks.glue.json + corruptDB.sqlite + distribution.ini + +[test_browserGlue_bookmarkshtml.js] +[test_browserGlue_corrupt.js] +[test_browserGlue_corrupt_nobackup.js] +[test_browserGlue_corrupt_nobackup_default.js] +[test_browserGlue_distribution.js] +[test_browserGlue_migrate.js] +[test_browserGlue_prefs.js] +[test_browserGlue_restore.js] +[test_clearHistory_shutdown.js] +[test_interactions_blocklist.js] +[test_invalid_defaultLocation.js] +[test_PUIU_batchUpdatesForNode.js] +[test_PUIU_setCharsetForPage.js] +[test_PUIU_title_difference_spotter.js] -- cgit v1.2.3