diff options
Diffstat (limited to 'browser/modules')
44 files changed, 0 insertions, 6721 deletions
diff --git a/browser/modules/moz.build b/browser/modules/moz.build index d71305198..852a4c911 100644 --- a/browser/modules/moz.build +++ b/browser/modules/moz.build @@ -4,12 +4,6 @@ # 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/. -BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] -XPCSHELL_TESTS_MANIFESTS += [ - 'test/unit/social/xpcshell.ini', - 'test/xpcshell/xpcshell.ini', -] - EXTRA_JS_MODULES += [ 'AboutHome.jsm', 'AboutNewTab.jsm', diff --git a/browser/modules/test/.eslintrc.js b/browser/modules/test/.eslintrc.js deleted file mode 100644 index e2d7896f8..000000000 --- a/browser/modules/test/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../testing/mochitest/browser.eslintrc.js" - ] -}; diff --git a/browser/modules/test/browser.ini b/browser/modules/test/browser.ini deleted file mode 100644 index af624439c..000000000 --- a/browser/modules/test/browser.ini +++ /dev/null @@ -1,42 +0,0 @@ -[DEFAULT] -support-files = - head.js - -[browser_BrowserUITelemetry_buckets.js] -[browser_BrowserUITelemetry_defaults.js] -[browser_BrowserUITelemetry_sidebar.js] -[browser_BrowserUITelemetry_syncedtabs.js] -[browser_ContentSearch.js] -skip-if = true # Bug 1308343 -support-files = - contentSearch.js - contentSearchBadImage.xml - contentSearchSuggestions.sjs - contentSearchSuggestions.xml - !/browser/components/search/test/head.js - !/browser/components/search/test/testEngine.xml -[browser_NetworkPrioritizer.js] -[browser_PermissionUI.js] -[browser_ProcessHangNotifications.js] -skip-if = !e10s -[browser_SelfSupportBackend.js] -support-files = - ../../components/uitour/test/uitour.html - ../../components/uitour/UITour-lib.js -[browser_taskbar_preview.js] -skip-if = os != "win" -[browser_UnsubmittedCrashHandler.js] -run-if = crashreporter -[browser_UsageTelemetry.js] -[browser_UsageTelemetry_private_and_restore.js] -[browser_UsageTelemetry_urlbar.js] -support-files = - usageTelemetrySearchSuggestions.sjs - usageTelemetrySearchSuggestions.xml -[browser_UsageTelemetry_searchbar.js] -support-files = - usageTelemetrySearchSuggestions.sjs - usageTelemetrySearchSuggestions.xml -[browser_UsageTelemetry_content.js] -[browser_UsageTelemetry_content_aboutHome.js] -[browser_urlBar_zoom.js] diff --git a/browser/modules/test/browser_BrowserUITelemetry_buckets.js b/browser/modules/test/browser_BrowserUITelemetry_buckets.js deleted file mode 100644 index f55761705..000000000 --- a/browser/modules/test/browser_BrowserUITelemetry_buckets.js +++ /dev/null @@ -1,97 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/* - WHERE'S MAH BUCKET?! - \ - ___ - .-9 9 `\ - =(:(::)= ; - |||| \ - |||| `-. - ,\|\| `, - / \ - ; `'---., - | `\ - ; / | - \ | / - ) \ __,.--\ / - .-' \,..._\ \` .-' .-' - `-=`` `: | /-/-/` - `.__/ -*/ - -"use strict"; - - -add_task(function* testBUIT() { - let s = {}; - Components.utils.import("resource:///modules/BrowserUITelemetry.jsm", s); - let BUIT = s.BrowserUITelemetry; - - registerCleanupFunction(function() { - BUIT.setBucket(null); - }); - - - // setBucket - is(BUIT.currentBucket, BUIT.BUCKET_DEFAULT, "Bucket should be default bucket"); - BUIT.setBucket("mah-bucket"); - is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "mah-bucket", "Bucket should have correct name"); - BUIT.setBucket(null); - is(BUIT.currentBucket, BUIT.BUCKET_DEFAULT, "Bucket should be reset to default"); - - - // _toTimeStr - is(BUIT._toTimeStr(10), "10ms", "Checking time string reprentation, 10ms"); - is(BUIT._toTimeStr(1000 + 10), "1s10ms", "Checking time string reprentation, 1s10ms"); - is(BUIT._toTimeStr((20 * 1000) + 10), "20s10ms", "Checking time string reprentation, 20s10ms"); - is(BUIT._toTimeStr(60 * 1000), "1m", "Checking time string reprentation, 1m"); - is(BUIT._toTimeStr(3 * 60 * 1000), "3m", "Checking time string reprentation, 3m"); - is(BUIT._toTimeStr((3 * 60 * 1000) + 1), "3m1ms", "Checking time string reprentation, 3m1ms"); - is(BUIT._toTimeStr((60 * 60 * 1000) + (10 * 60 * 1000)), "1h10m", "Checking time string reprentation, 1h10m"); - is(BUIT._toTimeStr(100 * 60 * 60 * 1000), "100h", "Checking time string reprentation, 100h"); - - - // setExpiringBucket - BUIT.setExpiringBucket("walrus", [1001, 2001, 3001, 10001]); - is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "walrus" + BUIT.BUCKET_SEPARATOR + "1s1ms", - "Bucket should be expiring and have time step of 1s1ms"); - - yield waitForConditionPromise(function() { - return BUIT.currentBucket == (BUIT.BUCKET_PREFIX + "walrus" + BUIT.BUCKET_SEPARATOR + "2s1ms"); - }, "Bucket should be expiring and have time step of 2s1ms"); - - yield waitForConditionPromise(function() { - return BUIT.currentBucket == (BUIT.BUCKET_PREFIX + "walrus" + BUIT.BUCKET_SEPARATOR + "3s1ms"); - }, "Bucket should be expiring and have time step of 3s1ms"); - - - // Interupt previous expiring bucket - BUIT.setExpiringBucket("walrus2", [1002, 2002]); - is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "walrus2" + BUIT.BUCKET_SEPARATOR + "1s2ms", - "Should be new expiring bucket, with time step of 1s2ms"); - - yield waitForConditionPromise(function() { - return BUIT.currentBucket == (BUIT.BUCKET_PREFIX + "walrus2" + BUIT.BUCKET_SEPARATOR + "2s2ms"); - }, "Should be new expiring bucket, with time step of 2s2ms"); - - - // Let expiring bucket expire - yield waitForConditionPromise(function() { - return BUIT.currentBucket == BUIT.BUCKET_DEFAULT; - }, "Bucket should have expired, default bucket should now be active"); - - - // Interupt expiring bucket with normal bucket - BUIT.setExpiringBucket("walrus3", [1003, 2003]); - is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "walrus3" + BUIT.BUCKET_SEPARATOR + "1s3ms", - "Should be new expiring bucket, with time step of 1s3ms"); - - BUIT.setBucket("mah-bucket"); - is(BUIT.currentBucket, BUIT.BUCKET_PREFIX + "mah-bucket", "Bucket should have correct name"); - - yield waitForConditionPromise(function() { - return BUIT.currentBucket == (BUIT.BUCKET_PREFIX + "mah-bucket"); - }, "Next step of old expiring bucket shouldn't have progressed"); -}); diff --git a/browser/modules/test/browser_BrowserUITelemetry_defaults.js b/browser/modules/test/browser_BrowserUITelemetry_defaults.js deleted file mode 100644 index ced1bbce0..000000000 --- a/browser/modules/test/browser_BrowserUITelemetry_defaults.js +++ /dev/null @@ -1,37 +0,0 @@ -// The purpose of this test is to ensure that by default, BrowserUITelemetry -// isn't reporting any UI customizations. This is primarily so changes to -// customizableUI (eg, new buttons, button location changes) also have a -// corresponding BrowserUITelemetry change. - -function test() { - let s = {}; - Cu.import("resource:///modules/CustomizableUI.jsm", s); - Cu.import("resource:///modules/BrowserUITelemetry.jsm", s); - - let { CustomizableUI, BrowserUITelemetry } = s; - - // Bug 1278176 - DevEdition never has the UI in a default state by default. - if (!AppConstants.MOZ_DEV_EDITION) { - Assert.ok(CustomizableUI.inDefaultState, - "No other test should have left CUI in a dirty state."); - } - - let result = BrowserUITelemetry._getWindowMeasurements(window, 0); - - // Bug 1278176 - DevEdition always reports the developer-button is moved. - if (!AppConstants.MOZ_DEV_EDITION) { - Assert.deepEqual(result.defaultMoved, []); - } - Assert.deepEqual(result.nondefaultAdded, []); - // This one is a bit weird - the "social-share-button" is dynamically added - // to the toolbar as the feature is first used - but it's listed as being in - // the toolbar by default so it doesn't end up in nondefaultAdded once it - // is created. The end result is that it ends up in defaultRemoved before - // the feature has been activated. - // Bug 1273358 exists to fix this. - Assert.deepEqual(result.defaultRemoved, ["social-share-button"]); - - // And mochi insists there's only a single window with a single tab when - // starting a test, so check that for good measure. - Assert.deepEqual(result.visibleTabs, [1]); -} diff --git a/browser/modules/test/browser_BrowserUITelemetry_sidebar.js b/browser/modules/test/browser_BrowserUITelemetry_sidebar.js deleted file mode 100644 index 5f19eabd5..000000000 --- a/browser/modules/test/browser_BrowserUITelemetry_sidebar.js +++ /dev/null @@ -1,56 +0,0 @@ -// Test the sidebar counters in BrowserUITelemetry. -"use strict"; - -const { BrowserUITelemetry: BUIT } = Cu.import("resource:///modules/BrowserUITelemetry.jsm", {}); - -add_task(function* testSidebarOpenClose() { - // Reset BrowserUITelemetry's world. - BUIT._countableEvents = {}; - - yield SidebarUI.show("viewTabsSidebar"); - - let counts = BUIT._countableEvents[BUIT.currentBucket]; - - Assert.deepEqual(counts, { sidebar: { viewTabsSidebar: { show: 1 } } }); - yield SidebarUI.hide(); - Assert.deepEqual(counts, { sidebar: { viewTabsSidebar: { show: 1, hide: 1 } } }); - - yield SidebarUI.show("viewBookmarksSidebar"); - Assert.deepEqual(counts, { - sidebar: { - viewTabsSidebar: { show: 1, hide: 1 }, - viewBookmarksSidebar: { show: 1 }, - } - }); - // Re-open the tabs sidebar while bookmarks is open - bookmarks should - // record a close. - yield SidebarUI.show("viewTabsSidebar"); - Assert.deepEqual(counts, { - sidebar: { - viewTabsSidebar: { show: 2, hide: 1 }, - viewBookmarksSidebar: { show: 1, hide: 1 }, - } - }); - yield SidebarUI.hide(); - Assert.deepEqual(counts, { - sidebar: { - viewTabsSidebar: { show: 2, hide: 2 }, - viewBookmarksSidebar: { show: 1, hide: 1 }, - } - }); - // Toggle - this will re-open viewTabsSidebar - yield SidebarUI.toggle("viewTabsSidebar"); - Assert.deepEqual(counts, { - sidebar: { - viewTabsSidebar: { show: 3, hide: 2 }, - viewBookmarksSidebar: { show: 1, hide: 1 }, - } - }); - yield SidebarUI.toggle("viewTabsSidebar"); - Assert.deepEqual(counts, { - sidebar: { - viewTabsSidebar: { show: 3, hide: 3 }, - viewBookmarksSidebar: { show: 1, hide: 1 }, - } - }); -}); diff --git a/browser/modules/test/browser_BrowserUITelemetry_syncedtabs.js b/browser/modules/test/browser_BrowserUITelemetry_syncedtabs.js deleted file mode 100644 index d3e1eac57..000000000 --- a/browser/modules/test/browser_BrowserUITelemetry_syncedtabs.js +++ /dev/null @@ -1,114 +0,0 @@ -// Test the SyncedTabs counters in BrowserUITelemetry. -"use strict"; - -const { BrowserUITelemetry: BUIT } = Cu.import("resource:///modules/BrowserUITelemetry.jsm", {}); -const {SyncedTabs} = Cu.import("resource://services-sync/SyncedTabs.jsm", {}); - -function mockSyncedTabs() { - // Mock SyncedTabs.jsm - let mockedInternal = { - get isConfiguredToSyncTabs() { return true; }, - getTabClients() { - return Promise.resolve([ - { - id: "guid_desktop", - type: "client", - name: "My Desktop", - tabs: [ - { - title: "http://example.com/10", - lastUsed: 10, // the most recent - }, - ], - } - ]); - }, - syncTabs() { - return Promise.resolve(); - }, - hasSyncedThisSession: true, - }; - - let oldInternal = SyncedTabs._internal; - SyncedTabs._internal = mockedInternal; - - // configure our broadcasters so we are in the right state. - document.getElementById("sync-reauth-state").hidden = true; - document.getElementById("sync-setup-state").hidden = true; - document.getElementById("sync-syncnow-state").hidden = false; - - registerCleanupFunction(() => { - SyncedTabs._internal = oldInternal; - - document.getElementById("sync-reauth-state").hidden = true; - document.getElementById("sync-setup-state").hidden = false; - document.getElementById("sync-syncnow-state").hidden = true; - }); -} - -mockSyncedTabs(); - -function promiseTabsUpdated() { - return new Promise(resolve => { - Services.obs.addObserver(function onNotification(aSubject, aTopic, aData) { - Services.obs.removeObserver(onNotification, aTopic); - resolve(); - }, "synced-tabs-menu:test:tabs-updated", false); - }); -} - -add_task(function* test_menu() { - // Reset BrowserUITelemetry's world. - BUIT._countableEvents = {}; - - let tabsUpdated = promiseTabsUpdated(); - - // check the button's functionality - yield PanelUI.show(); - - let syncButton = document.getElementById("sync-button"); - syncButton.click(); - - yield tabsUpdated; - // Get our 1 tab and click on it. - let tabList = document.getElementById("PanelUI-remotetabs-tabslist"); - let tabEntry = tabList.firstChild.nextSibling; - tabEntry.click(); - - let counts = BUIT._countableEvents[BUIT.currentBucket]; - Assert.deepEqual(counts, { - "click-builtin-item": { "sync-button": { left: 1 } }, - "synced-tabs": { open: { "toolbarbutton-subview": 1 } }, - }); -}); - -add_task(function* test_sidebar() { - // Reset BrowserUITelemetry's world. - BUIT._countableEvents = {}; - - yield SidebarUI.show('viewTabsSidebar'); - - let syncedTabsDeckComponent = SidebarUI.browser.contentWindow.syncedTabsDeckComponent; - - syncedTabsDeckComponent._accountStatus = () => Promise.resolve(true); - - // Once the tabs container has been selected (which here means "'selected' - // added to the class list") we are ready to test. - let container = SidebarUI.browser.contentDocument.querySelector(".tabs-container"); - let promiseUpdated = BrowserTestUtils.waitForAttribute("class", container); - - yield syncedTabsDeckComponent.updatePanel(); - yield promiseUpdated; - - let selectedPanel = syncedTabsDeckComponent.container.querySelector(".sync-state.selected"); - let tab = selectedPanel.querySelector(".tab"); - tab.click(); - let counts = BUIT._countableEvents[BUIT.currentBucket]; - Assert.deepEqual(counts, { - sidebar: { - viewTabsSidebar: { show: 1 }, - }, - "synced-tabs": { open: { sidebar: 1 } } - }); - yield SidebarUI.hide(); -}); diff --git a/browser/modules/test/browser_ContentSearch.js b/browser/modules/test/browser_ContentSearch.js deleted file mode 100644 index 97bd6ac51..000000000 --- a/browser/modules/test/browser_ContentSearch.js +++ /dev/null @@ -1,425 +0,0 @@ -/* 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 TEST_MSG = "ContentSearchTest"; -const CONTENT_SEARCH_MSG = "ContentSearch"; -const TEST_CONTENT_SCRIPT_BASENAME = "contentSearch.js"; - -// This timeout is absurdly high to avoid random failures like bug 1087120. -// That bug was reported when the timeout was 5 seconds, so let's try 10. -const SUGGESTIONS_TIMEOUT = 10000; - -var gMsgMan; -/* eslint no-undef:"error" */ -/* import-globals-from ../../components/search/test/head.js */ -Services.scriptloader.loadSubScript( - "chrome://mochitests/content/browser/browser/components/search/test/head.js", - this); - -let originalEngine = Services.search.currentEngine; - -add_task(function* setup() { - yield promiseNewEngine("testEngine.xml", { - setAsCurrent: true, - testPath: "chrome://mochitests/content/browser/browser/components/search/test/", - }); - - registerCleanupFunction(() => { - Services.search.currentEngine = originalEngine; - }); -}); - -add_task(function* GetState() { - yield addTab(); - gMsgMan.sendAsyncMessage(TEST_MSG, { - type: "GetState", - }); - let msg = yield waitForTestMsg("State"); - checkMsg(msg, { - type: "State", - data: yield currentStateObj(), - }); -}); - -add_task(function* SetCurrentEngine() { - yield addTab(); - let newCurrentEngine = null; - let oldCurrentEngine = Services.search.currentEngine; - let engines = Services.search.getVisibleEngines(); - for (let engine of engines) { - if (engine != oldCurrentEngine) { - newCurrentEngine = engine; - break; - } - } - if (!newCurrentEngine) { - info("Couldn't find a non-selected search engine, " + - "skipping this part of the test"); - return; - } - gMsgMan.sendAsyncMessage(TEST_MSG, { - type: "SetCurrentEngine", - data: newCurrentEngine.name, - }); - let deferred = Promise.defer(); - Services.obs.addObserver(function obs(subj, topic, data) { - info("Test observed " + data); - if (data == "engine-current") { - ok(true, "Test observed engine-current"); - Services.obs.removeObserver(obs, "browser-search-engine-modified"); - deferred.resolve(); - } - }, "browser-search-engine-modified", false); - let searchPromise = waitForTestMsg("CurrentEngine"); - info("Waiting for test to observe engine-current..."); - yield deferred.promise; - let msg = yield searchPromise; - checkMsg(msg, { - type: "CurrentEngine", - data: yield currentEngineObj(newCurrentEngine), - }); - - Services.search.currentEngine = oldCurrentEngine; - msg = yield waitForTestMsg("CurrentEngine"); - checkMsg(msg, { - type: "CurrentEngine", - data: yield currentEngineObj(oldCurrentEngine), - }); -}); - -add_task(function* modifyEngine() { - yield addTab(); - let engine = Services.search.currentEngine; - let oldAlias = engine.alias; - engine.alias = "ContentSearchTest"; - let msg = yield waitForTestMsg("CurrentState"); - checkMsg(msg, { - type: "CurrentState", - data: yield currentStateObj(), - }); - engine.alias = oldAlias; - msg = yield waitForTestMsg("CurrentState"); - checkMsg(msg, { - type: "CurrentState", - data: yield currentStateObj(), - }); -}); - -add_task(function* search() { - yield addTab(); - let engine = Services.search.currentEngine; - let data = { - engineName: engine.name, - searchString: "ContentSearchTest", - healthReportKey: "ContentSearchTest", - searchPurpose: "ContentSearchTest", - }; - let submissionURL = - engine.getSubmission(data.searchString, "", data.whence).uri.spec; - gMsgMan.sendAsyncMessage(TEST_MSG, { - type: "Search", - data: data, - expectedURL: submissionURL, - }); - let msg = yield waitForTestMsg("loadStopped"); - Assert.equal(msg.data.url, submissionURL, "Correct search page loaded"); -}); - -add_task(function* searchInBackgroundTab() { - // This test is like search(), but it opens a new tab after starting a search - // in another. In other words, it performs a search in a background tab. The - // search page should be loaded in the same tab that performed the search, in - // the background tab. - yield addTab(); - let engine = Services.search.currentEngine; - let data = { - engineName: engine.name, - searchString: "ContentSearchTest", - healthReportKey: "ContentSearchTest", - searchPurpose: "ContentSearchTest", - }; - let submissionURL = - engine.getSubmission(data.searchString, "", data.whence).uri.spec; - gMsgMan.sendAsyncMessage(TEST_MSG, { - type: "Search", - data: data, - expectedURL: submissionURL, - }); - - let newTab = gBrowser.addTab(); - gBrowser.selectedTab = newTab; - registerCleanupFunction(() => gBrowser.removeTab(newTab)); - - let msg = yield waitForTestMsg("loadStopped"); - Assert.equal(msg.data.url, submissionURL, "Correct search page loaded"); -}); - -add_task(function* badImage() { - yield addTab(); - // If the bad image URI caused an exception to be thrown within ContentSearch, - // then we'll hang waiting for the CurrentState responses triggered by the new - // engine. That's what we're testing, and obviously it shouldn't happen. - let vals = yield waitForNewEngine("contentSearchBadImage.xml", 1); - let engine = vals[0]; - let finalCurrentStateMsg = vals[vals.length - 1]; - let expectedCurrentState = yield currentStateObj(); - let expectedEngine = - expectedCurrentState.engines.find(e => e.name == engine.name); - ok(!!expectedEngine, "Sanity check: engine should be in expected state"); - ok(expectedEngine.iconBuffer === null, - "Sanity check: icon array buffer of engine in expected state " + - "should be null: " + expectedEngine.iconBuffer); - checkMsg(finalCurrentStateMsg, { - type: "CurrentState", - data: expectedCurrentState, - }); - // Removing the engine triggers a final CurrentState message. Wait for it so - // it doesn't trip up subsequent tests. - Services.search.removeEngine(engine); - yield waitForTestMsg("CurrentState"); -}); - -add_task(function* GetSuggestions_AddFormHistoryEntry_RemoveFormHistoryEntry() { - yield addTab(); - - // Add the test engine that provides suggestions. - let vals = yield waitForNewEngine("contentSearchSuggestions.xml", 0); - let engine = vals[0]; - - let searchStr = "browser_ContentSearch.js-suggestions-"; - - // Add a form history suggestion and wait for Satchel to notify about it. - gMsgMan.sendAsyncMessage(TEST_MSG, { - type: "AddFormHistoryEntry", - data: searchStr + "form", - }); - let deferred = Promise.defer(); - Services.obs.addObserver(function onAdd(subj, topic, data) { - if (data == "formhistory-add") { - Services.obs.removeObserver(onAdd, "satchel-storage-changed"); - executeSoon(() => deferred.resolve()); - } - }, "satchel-storage-changed", false); - yield deferred.promise; - - // Send GetSuggestions using the test engine. Its suggestions should appear - // in the remote suggestions in the Suggestions response below. - gMsgMan.sendAsyncMessage(TEST_MSG, { - type: "GetSuggestions", - data: { - engineName: engine.name, - searchString: searchStr, - remoteTimeout: SUGGESTIONS_TIMEOUT, - }, - }); - - // Check the Suggestions response. - let msg = yield waitForTestMsg("Suggestions"); - checkMsg(msg, { - type: "Suggestions", - data: { - engineName: engine.name, - searchString: searchStr, - formHistory: [searchStr + "form"], - remote: [searchStr + "foo", searchStr + "bar"], - }, - }); - - // Delete the form history suggestion and wait for Satchel to notify about it. - gMsgMan.sendAsyncMessage(TEST_MSG, { - type: "RemoveFormHistoryEntry", - data: searchStr + "form", - }); - deferred = Promise.defer(); - Services.obs.addObserver(function onRemove(subj, topic, data) { - if (data == "formhistory-remove") { - Services.obs.removeObserver(onRemove, "satchel-storage-changed"); - executeSoon(() => deferred.resolve()); - } - }, "satchel-storage-changed", false); - yield deferred.promise; - - // Send GetSuggestions again. - gMsgMan.sendAsyncMessage(TEST_MSG, { - type: "GetSuggestions", - data: { - engineName: engine.name, - searchString: searchStr, - remoteTimeout: SUGGESTIONS_TIMEOUT, - }, - }); - - // The formHistory suggestions in the Suggestions response should be empty. - msg = yield waitForTestMsg("Suggestions"); - checkMsg(msg, { - type: "Suggestions", - data: { - engineName: engine.name, - searchString: searchStr, - formHistory: [], - remote: [searchStr + "foo", searchStr + "bar"], - }, - }); - - // Finally, clean up by removing the test engine. - Services.search.removeEngine(engine); - yield waitForTestMsg("CurrentState"); -}); - -function buffersEqual(actualArrayBuffer, expectedArrayBuffer) { - let expectedView = new Int8Array(expectedArrayBuffer); - let actualView = new Int8Array(actualArrayBuffer); - for (let i = 0; i < expectedView.length; i++) { - if (actualView[i] != expectedView[i]) { - return false; - } - } - return true; -} - -function arrayBufferEqual(actualArrayBuffer, expectedArrayBuffer) { - ok(actualArrayBuffer instanceof ArrayBuffer, "Actual value is ArrayBuffer."); - ok(expectedArrayBuffer instanceof ArrayBuffer, "Expected value is ArrayBuffer."); - Assert.equal(actualArrayBuffer.byteLength, expectedArrayBuffer.byteLength, - "Array buffers have the same length."); - ok(buffersEqual(actualArrayBuffer, expectedArrayBuffer), "Buffers are equal."); -} - -function checkArrayBuffers(actual, expected) { - if (actual instanceof ArrayBuffer) { - arrayBufferEqual(actual, expected); - } - if (typeof actual == "object") { - for (let i in actual) { - checkArrayBuffers(actual[i], expected[i]); - } - } -} - -function checkMsg(actualMsg, expectedMsgData) { - let actualMsgData = actualMsg.data; - SimpleTest.isDeeply(actualMsg.data, expectedMsgData, "Checking message"); - - // Engines contain ArrayBuffers which we have to compare byte by byte and - // not as Objects (like SimpleTest.isDeeply does). - checkArrayBuffers(actualMsgData, expectedMsgData); -} - -function waitForMsg(name, type) { - let deferred = Promise.defer(); - info("Waiting for " + name + " message " + type + "..."); - gMsgMan.addMessageListener(name, function onMsg(msg) { - info("Received " + name + " message " + msg.data.type + "\n"); - if (msg.data.type == type) { - gMsgMan.removeMessageListener(name, onMsg); - deferred.resolve(msg); - } - }); - return deferred.promise; -} - -function waitForTestMsg(type) { - return waitForMsg(TEST_MSG, type); -} - -function waitForNewEngine(basename, numImages) { - info("Waiting for engine to be added: " + basename); - - // Wait for the search events triggered by adding the new engine. - // engine-added engine-loaded - let expectedSearchEvents = ["CurrentState", "CurrentState"]; - // engine-changed for each of the images - for (let i = 0; i < numImages; i++) { - expectedSearchEvents.push("CurrentState"); - } - let eventPromises = expectedSearchEvents.map(e => waitForTestMsg(e)); - - // Wait for addEngine(). - let addDeferred = Promise.defer(); - let url = getRootDirectory(gTestPath) + basename; - Services.search.addEngine(url, null, "", false, { - onSuccess: function (engine) { - info("Search engine added: " + basename); - addDeferred.resolve(engine); - }, - onError: function (errCode) { - ok(false, "addEngine failed with error code " + errCode); - addDeferred.reject(); - }, - }); - - return Promise.all([addDeferred.promise].concat(eventPromises)); -} - -function addTab() { - let deferred = Promise.defer(); - let tab = gBrowser.addTab(); - gBrowser.selectedTab = tab; - tab.linkedBrowser.addEventListener("load", function load() { - tab.linkedBrowser.removeEventListener("load", load, true); - let url = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME; - gMsgMan = tab.linkedBrowser.messageManager; - gMsgMan.sendAsyncMessage(CONTENT_SEARCH_MSG, { - type: "AddToWhitelist", - data: ["about:blank"], - }); - waitForMsg(CONTENT_SEARCH_MSG, "AddToWhitelistAck").then(() => { - gMsgMan.loadFrameScript(url, false); - deferred.resolve(); - }); - }, true); - registerCleanupFunction(() => gBrowser.removeTab(tab)); - return deferred.promise; -} - -var currentStateObj = Task.async(function* () { - let state = { - engines: [], - currentEngine: yield currentEngineObj(), - }; - for (let engine of Services.search.getVisibleEngines()) { - let uri = engine.getIconURLBySize(16, 16); - state.engines.push({ - name: engine.name, - iconBuffer: yield arrayBufferFromDataURI(uri), - hidden: false, - }); - } - return state; -}); - -var currentEngineObj = Task.async(function* () { - let engine = Services.search.currentEngine; - let uriFavicon = engine.getIconURLBySize(16, 16); - let bundle = Services.strings.createBundle("chrome://global/locale/autocomplete.properties"); - return { - name: engine.name, - placeholder: bundle.formatStringFromName("searchWithEngine", [engine.name], 1), - iconBuffer: yield arrayBufferFromDataURI(uriFavicon), - }; -}); - -function arrayBufferFromDataURI(uri) { - if (!uri) { - return Promise.resolve(null); - } - let deferred = Promise.defer(); - let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]. - createInstance(Ci.nsIXMLHttpRequest); - xhr.open("GET", uri, true); - xhr.responseType = "arraybuffer"; - xhr.onerror = () => { - deferred.resolve(null); - }; - xhr.onload = () => { - deferred.resolve(xhr.response); - }; - try { - xhr.send(); - } - catch (err) { - return Promise.resolve(null); - } - return deferred.promise; -} diff --git a/browser/modules/test/browser_NetworkPrioritizer.js b/browser/modules/test/browser_NetworkPrioritizer.js deleted file mode 100644 index 91557b0fd..000000000 --- a/browser/modules/test/browser_NetworkPrioritizer.js +++ /dev/null @@ -1,165 +0,0 @@ -/* 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 for NetworkPrioritizer.jsm (Bug 514490) **/ - -const LOWEST = Ci.nsISupportsPriority.PRIORITY_LOWEST; -const LOW = Ci.nsISupportsPriority.PRIORITY_LOW; -const NORMAL = Ci.nsISupportsPriority.PRIORITY_NORMAL; -const HIGH = Ci.nsISupportsPriority.PRIORITY_HIGH; -const HIGHEST = Ci.nsISupportsPriority.PRIORITY_HIGHEST; - -const DELTA = NORMAL - LOW; // lower value means higher priority - -// Test helper functions. -// getPriority and setPriority can take a tab or a Browser -function* getPriority(aBrowser) { - if (aBrowser.localName == "tab") - aBrowser = aBrowser.linkedBrowser; - - return yield ContentTask.spawn(aBrowser, null, function* () { - return docShell.QueryInterface(Components.interfaces.nsIWebNavigation) - .QueryInterface(Components.interfaces.nsIDocumentLoader) - .loadGroup - .QueryInterface(Components.interfaces.nsISupportsPriority) - .priority; - }); -} - -function* setPriority(aBrowser, aPriority) { - if (aBrowser.localName == "tab") - aBrowser = aBrowser.linkedBrowser; - - yield ContentTask.spawn(aBrowser, aPriority, function* (aPriority) { - docShell.QueryInterface(Components.interfaces.nsIWebNavigation) - .QueryInterface(Components.interfaces.nsIDocumentLoader) - .loadGroup - .QueryInterface(Ci.nsISupportsPriority) - .priority = aPriority; - }); -} - -function* isWindowState(aWindow, aTabPriorities) { - let browsers = aWindow.gBrowser.browsers; - // Make sure we have the right number of tabs & priorities - is(browsers.length, aTabPriorities.length, - "Window has expected number of tabs"); - // aState should be in format [ priority, priority, priority ] - for (let i = 0; i < browsers.length; i++) { - is(yield getPriority(browsers[i]), aTabPriorities[i], - "Tab " + i + " had expected priority"); - } -} - -function promiseWaitForFocus(aWindow) { - return new Promise((resolve) => { - waitForFocus(resolve, aWindow); - }); -} - -add_task(function*() { - // This is the real test. It creates multiple tabs & windows, changes focus, - // closes windows/tabs to make sure we behave correctly. - // This test assumes that no priorities have been adjusted and the loadgroup - // priority starts at 0. - - // Call window "window_A" to make the test easier to follow - let window_A = window; - - // Test 1 window, 1 tab case. - yield isWindowState(window_A, [HIGH]); - - // Exising tab is tab_A1 - let tab_A2 = window_A.gBrowser.addTab("http://example.com"); - let tab_A3 = window_A.gBrowser.addTab("about:config"); - yield BrowserTestUtils.browserLoaded(tab_A3.linkedBrowser); - - // tab_A2 isn't focused yet - yield isWindowState(window_A, [HIGH, NORMAL, NORMAL]); - - // focus tab_A2 & make sure priority got updated - window_A.gBrowser.selectedTab = tab_A2; - yield isWindowState(window_A, [NORMAL, HIGH, NORMAL]); - - window_A.gBrowser.removeTab(tab_A2); - // Next tab is auto selected synchronously as part of removeTab, and we - // expect the priority to be updated immediately. - yield isWindowState(window_A, [NORMAL, HIGH]); - - // Open another window then play with focus - let window_B = yield BrowserTestUtils.openNewBrowserWindow(); - - yield promiseWaitForFocus(window_B); - yield isWindowState(window_A, [LOW, NORMAL]); - yield isWindowState(window_B, [HIGH]); - - yield promiseWaitForFocus(window_A); - yield isWindowState(window_A, [NORMAL, HIGH]); - yield isWindowState(window_B, [NORMAL]); - - yield promiseWaitForFocus(window_B); - yield isWindowState(window_A, [LOW, NORMAL]); - yield isWindowState(window_B, [HIGH]); - - // Cleanup - window_A.gBrowser.removeTab(tab_A3); - yield BrowserTestUtils.closeWindow(window_B); -}); - -add_task(function*() { - // This is more a test of nsLoadGroup and how it handles priorities. But since - // we depend on its behavior, it's good to test it. This is testing that there - // are no errors if we adjust beyond nsISupportsPriority's bounds. - - yield promiseWaitForFocus(); - - let tab1 = gBrowser.tabs[0]; - let oldPriority = yield getPriority(tab1); - - // Set the priority of tab1 to the lowest possible. Selecting the other tab - // will try to lower it - yield setPriority(tab1, LOWEST); - - let tab2 = gBrowser.addTab("http://example.com"); - yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser); - gBrowser.selectedTab = tab2; - is(yield getPriority(tab1), LOWEST - DELTA, "Can adjust priority beyond 'lowest'"); - - // Now set priority to "highest" and make sure that no errors occur. - yield setPriority(tab1, HIGHEST); - gBrowser.selectedTab = tab1; - - is(yield getPriority(tab1), HIGHEST + DELTA, "Can adjust priority beyond 'highest'"); - - // Cleanup - gBrowser.removeTab(tab2); - yield setPriority(tab1, oldPriority); -}); - -add_task(function*() { - // This tests that the priority doesn't get lost when switching the browser's remoteness - - if (!gMultiProcessBrowser) { - return; - } - - let browser = gBrowser.selectedBrowser; - - browser.loadURI("http://example.com"); - yield BrowserTestUtils.browserLoaded(browser); - ok(browser.isRemoteBrowser, "web page should be loaded in remote browser"); - is(yield getPriority(browser), HIGH, "priority of selected tab should be 'high'"); - - browser.loadURI("about:rights"); - yield BrowserTestUtils.browserLoaded(browser); - ok(!browser.isRemoteBrowser, "about:rights should switch browser to non-remote"); - is(yield getPriority(browser), HIGH, - "priority of selected tab should be 'high' when going from remote to non-remote"); - - browser.loadURI("http://example.com"); - yield BrowserTestUtils.browserLoaded(browser); - ok(browser.isRemoteBrowser, "going from about:rights to web page should switch browser to remote"); - is(yield getPriority(browser), HIGH, - "priority of selected tab should be 'high' when going from non-remote to remote"); -}); diff --git a/browser/modules/test/browser_PermissionUI.js b/browser/modules/test/browser_PermissionUI.js deleted file mode 100644 index 006bc5e66..000000000 --- a/browser/modules/test/browser_PermissionUI.js +++ /dev/null @@ -1,445 +0,0 @@ -/** - * These tests test the ability for the PermissionUI module to open - * permission prompts to the user. It also tests to ensure that - * add-ons can introduce their own permission prompts. - */ - -"use strict"; - -Cu.import("resource://gre/modules/Integration.jsm", this); -Cu.import("resource:///modules/PermissionUI.jsm", this); - -/** - * Given a <xul:browser> at some non-internal web page, - * return something that resembles an nsIContentPermissionRequest, - * using the browsers currently loaded document to get a principal. - * - * @param browser (<xul:browser>) - * The browser that we'll create a nsIContentPermissionRequest - * for. - * @returns A nsIContentPermissionRequest-ish object. - */ -function makeMockPermissionRequest(browser) { - let result = { - types: null, - principal: browser.contentPrincipal, - requester: null, - _cancelled: false, - cancel() { - this._cancelled = true; - }, - _allowed: false, - allow() { - this._allowed = true; - }, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionRequest]), - }; - - // In the e10s-case, nsIContentPermissionRequest will have - // element defined. window is defined otherwise. - if (browser.isRemoteBrowser) { - result.element = browser; - } else { - result.window = browser.contentWindow; - } - - return result; -} - -/** - * For an opened PopupNotification, clicks on the main action, - * and waits for the panel to fully close. - * - * @return {Promise} - * Resolves once the panel has fired the "popuphidden" - * event. - */ -function clickMainAction() { - let removePromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden"); - let popupNotification = getPopupNotificationNode(); - popupNotification.button.click(); - return removePromise; -} - -/** - * For an opened PopupNotification, clicks on a secondary action, - * and waits for the panel to fully close. - * - * @param {int} index - * The 0-indexed index of the secondary menuitem to choose. - * @return {Promise} - * Resolves once the panel has fired the "popuphidden" - * event. - */ -function clickSecondaryAction(index) { - let removePromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden"); - let popupNotification = getPopupNotificationNode(); - let menuitems = popupNotification.children; - menuitems[index].click(); - return removePromise; -} - -/** - * Makes sure that 1 (and only 1) <xul:popupnotification> is being displayed - * by PopupNotification, and then returns that <xul:popupnotification>. - * - * @return {<xul:popupnotification>} - */ -function getPopupNotificationNode() { - // PopupNotification is a bit overloaded here, so to be - // clear, popupNotifications is a list of <xul:popupnotification> - // nodes. - let popupNotifications = PopupNotifications.panel.childNodes; - Assert.equal(popupNotifications.length, 1, - "Should be showing a <xul:popupnotification>"); - return popupNotifications[0]; -} - -/** - * Tests the PermissionPromptForRequest prototype to ensure that a prompt - * can be displayed. Does not test permission handling. - */ -add_task(function* test_permission_prompt_for_request() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "http://example.com/", - }, function*(browser) { - const kTestNotificationID = "test-notification"; - const kTestMessage = "Test message"; - let mainAction = { - label: "Main", - accessKey: "M", - }; - let secondaryAction = { - label: "Secondary", - accessKey: "S", - }; - - let mockRequest = makeMockPermissionRequest(browser); - let TestPrompt = { - __proto__: PermissionUI.PermissionPromptForRequestPrototype, - request: mockRequest, - notificationID: kTestNotificationID, - message: kTestMessage, - promptActions: [mainAction, secondaryAction], - }; - - let shownPromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - TestPrompt.prompt(); - yield shownPromise; - let notification = - PopupNotifications.getNotification(kTestNotificationID, browser); - Assert.ok(notification, "Should have gotten the notification"); - - Assert.equal(notification.message, kTestMessage, - "Should be showing the right message"); - Assert.equal(notification.mainAction.label, mainAction.label, - "The main action should have the right label"); - Assert.equal(notification.mainAction.accessKey, mainAction.accessKey, - "The main action should have the right access key"); - Assert.equal(notification.secondaryActions.length, 1, - "There should only be 1 secondary action"); - Assert.equal(notification.secondaryActions[0].label, secondaryAction.label, - "The secondary action should have the right label"); - Assert.equal(notification.secondaryActions[0].accessKey, - secondaryAction.accessKey, - "The secondary action should have the right access key"); - Assert.ok(notification.options.displayURI.equals(mockRequest.principal.URI), - "Should be showing the URI of the requesting page"); - - let removePromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden"); - notification.remove(); - yield removePromise; - }); -}); - -/** - * Tests that if the PermissionPrompt sets displayURI to false in popupOptions, - * then there is no URI shown on the popupnotification. - */ -add_task(function* test_permission_prompt_for_popupOptions() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "http://example.com/", - }, function*(browser) { - const kTestNotificationID = "test-notification"; - const kTestMessage = "Test message"; - let mainAction = { - label: "Main", - accessKey: "M", - }; - let secondaryAction = { - label: "Secondary", - accessKey: "S", - }; - - let mockRequest = makeMockPermissionRequest(browser); - let TestPrompt = { - __proto__: PermissionUI.PermissionPromptForRequestPrototype, - request: mockRequest, - notificationID: kTestNotificationID, - message: kTestMessage, - promptActions: [mainAction, secondaryAction], - popupOptions: { - displayURI: false, - }, - }; - - let shownPromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - TestPrompt.prompt(); - yield shownPromise; - let notification = - PopupNotifications.getNotification(kTestNotificationID, browser); - - Assert.ok(!notification.options.displayURI, - "Should not show the URI of the requesting page"); - - let removePromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden"); - notification.remove(); - yield removePromise; - }); -}); - -/** - * Tests that if the PermissionPrompt has the permissionKey - * set that permissions can be set properly by the user. Also - * ensures that callbacks for promptActions are properly fired. - */ -add_task(function* test_with_permission_key() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "http://example.com", - }, function*(browser) { - const kTestNotificationID = "test-notification"; - const kTestMessage = "Test message"; - const kTestPermissionKey = "test-permission-key"; - - let allowed = false; - let mainAction = { - label: "Allow", - accessKey: "M", - action: Ci.nsIPermissionManager.ALLOW_ACTION, - expiryType: Ci.nsIPermissionManager.EXPIRE_SESSION, - callback: function() { - allowed = true; - } - }; - - let denied = false; - let secondaryAction = { - label: "Deny", - accessKey: "D", - action: Ci.nsIPermissionManager.DENY_ACTION, - expiryType: Ci.nsIPermissionManager.EXPIRE_SESSION, - callback: function() { - denied = true; - } - }; - - let mockRequest = makeMockPermissionRequest(browser); - let principal = mockRequest.principal; - registerCleanupFunction(function() { - Services.perms.removeFromPrincipal(principal, kTestPermissionKey); - }); - - let TestPrompt = { - __proto__: PermissionUI.PermissionPromptForRequestPrototype, - request: mockRequest, - notificationID: kTestNotificationID, - permissionKey: kTestPermissionKey, - message: kTestMessage, - promptActions: [mainAction, secondaryAction], - }; - - let shownPromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - TestPrompt.prompt(); - yield shownPromise; - let notification = - PopupNotifications.getNotification(kTestNotificationID, browser); - Assert.ok(notification, "Should have gotten the notification"); - - let curPerm = - Services.perms.testPermissionFromPrincipal(principal, - kTestPermissionKey); - Assert.equal(curPerm, Ci.nsIPermissionManager.UNKNOWN_ACTION, - "Should be no permission set to begin with."); - - // First test denying the permission request. - Assert.equal(notification.secondaryActions.length, 1, - "There should only be 1 secondary action"); - yield clickSecondaryAction(0); - curPerm = Services.perms.testPermissionFromPrincipal(principal, - kTestPermissionKey); - Assert.equal(curPerm, Ci.nsIPermissionManager.DENY_ACTION, - "Should have denied the action"); - Assert.ok(denied, "The secondaryAction callback should have fired"); - Assert.ok(!allowed, "The mainAction callback should not have fired"); - Assert.ok(mockRequest._cancelled, - "The request should have been cancelled"); - Assert.ok(!mockRequest._allowed, - "The request should not have been allowed"); - - // Clear the permission and pretend we never denied - Services.perms.removeFromPrincipal(principal, kTestPermissionKey); - denied = false; - mockRequest._cancelled = false; - - // Bring the PopupNotification back up now... - shownPromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - TestPrompt.prompt(); - yield shownPromise; - - // Next test allowing the permission request. - yield clickMainAction(); - curPerm = Services.perms.testPermissionFromPrincipal(principal, - kTestPermissionKey); - Assert.equal(curPerm, Ci.nsIPermissionManager.ALLOW_ACTION, - "Should have allowed the action"); - Assert.ok(!denied, "The secondaryAction callback should not have fired"); - Assert.ok(allowed, "The mainAction callback should have fired"); - Assert.ok(!mockRequest._cancelled, - "The request should not have been cancelled"); - Assert.ok(mockRequest._allowed, - "The request should have been allowed"); - }); -}); - -/** - * Tests that the onBeforeShow method will be called before - * the popup appears. - */ -add_task(function* test_on_before_show() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "http://example.com", - }, function*(browser) { - const kTestNotificationID = "test-notification"; - const kTestMessage = "Test message"; - - let mainAction = { - label: "Test action", - accessKey: "T", - }; - - let mockRequest = makeMockPermissionRequest(browser); - let beforeShown = false; - - let TestPrompt = { - __proto__: PermissionUI.PermissionPromptForRequestPrototype, - request: mockRequest, - notificationID: kTestNotificationID, - message: kTestMessage, - promptActions: [mainAction], - onBeforeShow() { - beforeShown = true; - } - }; - - let shownPromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - TestPrompt.prompt(); - Assert.ok(beforeShown, "Should have called onBeforeShown"); - yield shownPromise; - let notification = - PopupNotifications.getNotification(kTestNotificationID, browser); - - let removePromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden"); - notification.remove(); - yield removePromise; - }); -}); - -/** - * Tests that we can open a PermissionPrompt without wrapping a - * nsIContentPermissionRequest. - */ -add_task(function* test_no_request() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "http://example.com", - }, function*(browser) { - const kTestNotificationID = "test-notification"; - let allowed = false; - let mainAction = { - label: "Allow", - accessKey: "M", - callback: function() { - allowed = true; - } - }; - - let denied = false; - let secondaryAction = { - label: "Deny", - accessKey: "D", - callback: function() { - denied = true; - } - }; - - const kTestMessage = "Test message with no request"; - let principal = browser.contentPrincipal; - let beforeShown = false; - - let TestPrompt = { - __proto__: PermissionUI.PermissionPromptPrototype, - notificationID: kTestNotificationID, - principal, - browser, - message: kTestMessage, - promptActions: [mainAction, secondaryAction], - onBeforeShow() { - beforeShown = true; - } - }; - - let shownPromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - TestPrompt.prompt(); - Assert.ok(beforeShown, "Should have called onBeforeShown"); - yield shownPromise; - let notification = - PopupNotifications.getNotification(kTestNotificationID, browser); - - Assert.equal(notification.message, kTestMessage, - "Should be showing the right message"); - Assert.equal(notification.mainAction.label, mainAction.label, - "The main action should have the right label"); - Assert.equal(notification.mainAction.accessKey, mainAction.accessKey, - "The main action should have the right access key"); - Assert.equal(notification.secondaryActions.length, 1, - "There should only be 1 secondary action"); - Assert.equal(notification.secondaryActions[0].label, secondaryAction.label, - "The secondary action should have the right label"); - Assert.equal(notification.secondaryActions[0].accessKey, - secondaryAction.accessKey, - "The secondary action should have the right access key"); - Assert.ok(notification.options.displayURI.equals(principal.URI), - "Should be showing the URI of the requesting page"); - - // First test denying the permission request. - Assert.equal(notification.secondaryActions.length, 1, - "There should only be 1 secondary action"); - yield clickSecondaryAction(0); - Assert.ok(denied, "The secondaryAction callback should have fired"); - Assert.ok(!allowed, "The mainAction callback should not have fired"); - - shownPromise = - BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - TestPrompt.prompt(); - yield shownPromise; - - // Next test allowing the permission request. - yield clickMainAction(); - Assert.ok(allowed, "The mainAction callback should have fired"); - }); -}); diff --git a/browser/modules/test/browser_ProcessHangNotifications.js b/browser/modules/test/browser_ProcessHangNotifications.js deleted file mode 100644 index 597be611a..000000000 --- a/browser/modules/test/browser_ProcessHangNotifications.js +++ /dev/null @@ -1,189 +0,0 @@ - -Cu.import("resource://gre/modules/UpdateUtils.jsm"); - -function getNotificationBox(aWindow) { - return aWindow.document.getElementById("high-priority-global-notificationbox"); -} - -function promiseNotificationShown(aWindow, aName) { - return new Promise((resolve) => { - let notification = getNotificationBox(aWindow); - notification.addEventListener("AlertActive", function active() { - notification.removeEventListener("AlertActive", active, true); - is(notification.allNotifications.length, 1, "Notification Displayed."); - resolve(notification); - }); - }); -} - -function promiseReportCallMade(aValue) { - return new Promise((resolve) => { - let old = gTestHangReport.testCallback; - gTestHangReport.testCallback = function (val) { - gTestHangReport.testCallback = old; - is(aValue, val, "was the correct method call made on the hang report object?"); - resolve(); - }; - }); -} - -function pushPrefs(...aPrefs) { - return new Promise((resolve) => { - SpecialPowers.pushPrefEnv({"set": aPrefs}, resolve); - resolve(); - }); -} - -function popPrefs() { - return new Promise((resolve) => { - SpecialPowers.popPrefEnv(resolve); - resolve(); - }); -} - -let gTestHangReport = { - SLOW_SCRIPT: 1, - PLUGIN_HANG: 2, - - TEST_CALLBACK_CANCELED: 1, - TEST_CALLBACK_TERMSCRIPT: 2, - TEST_CALLBACK_TERMPLUGIN: 3, - - _hangType: 1, - _tcb: function (aCallbackType) {}, - - get hangType() { - return this._hangType; - }, - - set hangType(aValue) { - this._hangType = aValue; - }, - - set testCallback(aValue) { - this._tcb = aValue; - }, - - QueryInterface: function (aIID) { - if (aIID.equals(Components.interfaces.nsIHangReport) || - aIID.equals(Components.interfaces.nsISupports)) - return this; - throw Components.results.NS_NOINTERFACE; - }, - - userCanceled: function () { - this._tcb(this.TEST_CALLBACK_CANCELED); - }, - - terminateScript: function () { - this._tcb(this.TEST_CALLBACK_TERMSCRIPT); - }, - - terminatePlugin: function () { - this._tcb(this.TEST_CALLBACK_TERMPLUGIN); - }, - - isReportForBrowser: function(aFrameLoader) { - return true; - } -}; - -// on dev edition we add a button for js debugging of hung scripts. -let buttonCount = (UpdateUtils.UpdateChannel == "aurora" ? 3 : 2); - -/** - * Test if hang reports receive a terminate script callback when the user selects - * stop in response to a script hang. - */ - -add_task(function* terminateScriptTest() { - let promise = promiseNotificationShown(window, "process-hang"); - Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null); - let notification = yield promise; - - let buttons = notification.currentNotification.getElementsByTagName("button"); - // Fails on aurora on-push builds, bug 1232204 - // is(buttons.length, buttonCount, "proper number of buttons"); - - // Click the "Stop It" button, we should get a terminate script callback - gTestHangReport.hangType = gTestHangReport.SLOW_SCRIPT; - promise = promiseReportCallMade(gTestHangReport.TEST_CALLBACK_TERMSCRIPT); - buttons[0].click(); - yield promise; -}); - -/** - * Test if hang reports receive user canceled callbacks after a user selects wait - * and the browser frees up from a script hang on its own. - */ - -add_task(function* waitForScriptTest() { - let promise = promiseNotificationShown(window, "process-hang"); - Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null); - let notification = yield promise; - - let buttons = notification.currentNotification.getElementsByTagName("button"); - // Fails on aurora on-push builds, bug 1232204 - // is(buttons.length, buttonCount, "proper number of buttons"); - - yield pushPrefs(["browser.hangNotification.waitPeriod", 1000]); - - function nocbcheck() { - ok(false, "received a callback?"); - } - let oldcb = gTestHangReport.testCallback; - gTestHangReport.testCallback = nocbcheck; - // Click the "Wait" button this time, we shouldn't get a callback at all. - buttons[1].click(); - gTestHangReport.testCallback = oldcb; - - // send another hang pulse, we should not get a notification here - Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null); - is(notification.currentNotification, null, "no notification should be visible"); - - gTestHangReport.testCallback = function() {}; - Services.obs.notifyObservers(gTestHangReport, "clear-hang-report", null); - gTestHangReport.testCallback = oldcb; - - yield popPrefs(); -}); - -/** - * Test if hang reports receive user canceled callbacks after the content - * process stops sending hang notifications. - */ - -add_task(function* hangGoesAwayTest() { - yield pushPrefs(["browser.hangNotification.expiration", 1000]); - - let promise = promiseNotificationShown(window, "process-hang"); - Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null); - yield promise; - - promise = promiseReportCallMade(gTestHangReport.TEST_CALLBACK_CANCELED); - Services.obs.notifyObservers(gTestHangReport, "clear-hang-report", null); - yield promise; - - yield popPrefs(); -}); - -/** - * Tests if hang reports receive a terminate plugin callback when the user selects - * stop in response to a plugin hang. - */ - -add_task(function* terminatePluginTest() { - let promise = promiseNotificationShown(window, "process-hang"); - Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null); - let notification = yield promise; - - let buttons = notification.currentNotification.getElementsByTagName("button"); - // Fails on aurora on-push builds, bug 1232204 - // is(buttons.length, buttonCount, "proper number of buttons"); - - // Click the "Stop It" button, we should get a terminate script callback - gTestHangReport.hangType = gTestHangReport.PLUGIN_HANG; - promise = promiseReportCallMade(gTestHangReport.TEST_CALLBACK_TERMPLUGIN); - buttons[0].click(); - yield promise; -}); diff --git a/browser/modules/test/browser_SelfSupportBackend.js b/browser/modules/test/browser_SelfSupportBackend.js deleted file mode 100644 index 9e2c1d181..000000000 --- a/browser/modules/test/browser_SelfSupportBackend.js +++ /dev/null @@ -1,214 +0,0 @@ -/* 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/. */ - -"use strict"; - -// Pass an empty scope object to the import to prevent "leaked window property" -// errors in tests. -var Preferences = Cu.import("resource://gre/modules/Preferences.jsm", {}).Preferences; -var PromiseUtils = Cu.import("resource://gre/modules/PromiseUtils.jsm", {}).PromiseUtils; -var SelfSupportBackend = - Cu.import("resource:///modules/SelfSupportBackend.jsm", {}).SelfSupportBackend; - -const PREF_SELFSUPPORT_ENABLED = "browser.selfsupport.enabled"; -const PREF_SELFSUPPORT_URL = "browser.selfsupport.url"; -const PREF_UITOUR_ENABLED = "browser.uitour.enabled"; - -const TEST_WAIT_RETRIES = 60; - -const TEST_PAGE_URL = getRootDirectory(gTestPath) + "uitour.html"; -const TEST_PAGE_URL_HTTPS = TEST_PAGE_URL.replace("chrome://mochitests/content/", "https://example.com/"); - -function sendSessionRestoredNotification() { - let selfSupportBackendImpl = - Cu.import("resource:///modules/SelfSupportBackend.jsm", {}).SelfSupportBackendInternal; - selfSupportBackendImpl.observe(null, "sessionstore-windows-restored", null); -} - -/** - * Find a browser, with an IFRAME as parent, who has aURL as the source attribute. - * - * @param aURL The URL to look for to identify the browser. - * - * @returns {Object} The browser element or null on failure. - */ -function findSelfSupportBrowser(aURL) { - let frames = Services.appShell.hiddenDOMWindow.document.querySelectorAll('iframe'); - for (let frame of frames) { - try { - let browser = frame.contentDocument.getElementById("win").querySelectorAll('browser')[0]; - let url = browser.getAttribute("src"); - if (url == aURL) { - return browser; - } - } catch (e) { - continue; - } - } - return null; -} - -/** - * Wait for self support page to load. - * - * @param aURL The URL to look for to identify the browser. - * - * @returns {Promise} Return a promise which is resolved when SelfSupport page is fully - * loaded. - */ -function promiseSelfSupportLoad(aURL) { - return new Promise((resolve, reject) => { - // Find the SelfSupport browser. - let browserPromise = waitForConditionPromise(() => !!findSelfSupportBrowser(aURL), - "SelfSupport browser not found.", - TEST_WAIT_RETRIES); - - // Once found, append a "load" listener to catch page loads. - browserPromise.then(() => { - let browser = findSelfSupportBrowser(aURL); - if (browser.contentDocument.readyState === "complete") { - resolve(browser); - } else { - let handler = () => { - browser.removeEventListener("load", handler, true); - resolve(browser); - }; - browser.addEventListener("load", handler, true); - } - }, reject); - }); -} - -/** - * Wait for self support to close. - * - * @param aURL The URL to look for to identify the browser. - * - * @returns {Promise} Return a promise which is resolved when SelfSupport browser cannot - * be found anymore. - */ -function promiseSelfSupportClose(aURL) { - return waitForConditionPromise(() => !findSelfSupportBrowser(aURL), - "SelfSupport browser is still open.", TEST_WAIT_RETRIES); -} - -/** - * Prepare the test environment. - */ -add_task(function* setupEnvironment() { - // We always run the SelfSupportBackend in tests to check for weird behaviours. - // Disable it to test its start-up. - SelfSupportBackend.uninit(); - - // Testing prefs are set via |user_pref|, so we need to get their value in order - // to restore them. - let selfSupportEnabled = Preferences.get(PREF_SELFSUPPORT_ENABLED, true); - let uitourEnabled = Preferences.get(PREF_UITOUR_ENABLED, false); - let selfSupportURL = Preferences.get(PREF_SELFSUPPORT_URL, ""); - - // Enable the SelfSupport backend and set the page URL. We also make sure UITour - // is enabled. - Preferences.set(PREF_SELFSUPPORT_ENABLED, true); - Preferences.set(PREF_UITOUR_ENABLED, true); - Preferences.set(PREF_SELFSUPPORT_URL, TEST_PAGE_URL_HTTPS); - - // Whitelist the HTTPS page to use UITour. - let pageURI = Services.io.newURI(TEST_PAGE_URL_HTTPS, null, null); - Services.perms.add(pageURI, "uitour", Services.perms.ALLOW_ACTION); - - registerCleanupFunction(() => { - Services.perms.remove(pageURI, "uitour"); - Preferences.set(PREF_SELFSUPPORT_ENABLED, selfSupportEnabled); - Preferences.set(PREF_UITOUR_ENABLED, uitourEnabled); - Preferences.set(PREF_SELFSUPPORT_URL, selfSupportURL); - }); -}); - -/** - * Test that the self support page can use the UITour API and close itself. - */ -add_task(function* test_selfSupport() { - // Initialise the SelfSupport backend and trigger the load. - SelfSupportBackend.init(); - - // SelfSupportBackend waits for "sessionstore-windows-restored" to start loading. Send it. - info("Sending sessionstore-windows-restored"); - sendSessionRestoredNotification(); - - // Wait for the SelfSupport page to load. - info("Waiting for the SelfSupport local page to load."); - let selfSupportBrowser = yield promiseSelfSupportLoad(TEST_PAGE_URL_HTTPS); - Assert.ok(!!selfSupportBrowser, "SelfSupport browser must exist."); - - // Get a reference to the UITour API. - info("Testing access to the UITour API."); - let contentWindow = - Cu.waiveXrays(selfSupportBrowser.contentDocument.defaultView); - let uitourAPI = contentWindow.Mozilla.UITour; - - // Test the UITour API with a ping. - let pingPromise = new Promise((resolve) => { - uitourAPI.ping(resolve); - }); - yield pingPromise; - info("Ping succeeded"); - - let observePromise = ContentTask.spawn(selfSupportBrowser, null, function* checkObserve() { - yield new Promise(resolve => { - let win = Cu.waiveXrays(content); - win.Mozilla.UITour.observe((event, data) => { - if (event != "Heartbeat:Engaged") { - return; - } - Assert.equal(data.flowId, "myFlowID", "Check flowId"); - Assert.ok(!!data.timestamp, "Check timestamp"); - resolve(data); - }, () => {}); - }); - }); - - info("Notifying Heartbeat:Engaged"); - UITour.notify("Heartbeat:Engaged", { - flowId: "myFlowID", - timestamp: Date.now(), - }); - yield observePromise; - info("Observed in the hidden frame"); - - // Close SelfSupport from content. - contentWindow.close(); - - // Wait until SelfSupport closes. - info("Waiting for the SelfSupport to close."); - yield promiseSelfSupportClose(TEST_PAGE_URL_HTTPS); - - // Find the SelfSupport browser, again. We don't expect to find it. - selfSupportBrowser = findSelfSupportBrowser(TEST_PAGE_URL_HTTPS); - Assert.ok(!selfSupportBrowser, "SelfSupport browser must not exist."); - - // We shouldn't need this, but let's keep it to make sure closing SelfSupport twice - // doesn't create any problem. - SelfSupportBackend.uninit(); -}); - -/** - * Test that SelfSupportBackend only allows HTTPS. - */ -add_task(function* test_selfSupport_noHTTPS() { - Preferences.set(PREF_SELFSUPPORT_URL, TEST_PAGE_URL); - - SelfSupportBackend.init(); - - // SelfSupportBackend waits for "sessionstore-windows-restored" to start loading. Send it. - info("Sending sessionstore-windows-restored"); - sendSessionRestoredNotification(); - - // Find the SelfSupport browser. We don't expect to find it since we are not using https. - let selfSupportBrowser = findSelfSupportBrowser(TEST_PAGE_URL); - Assert.ok(!selfSupportBrowser, "SelfSupport browser must not exist."); - - // We shouldn't need this, but let's keep it to make sure closing SelfSupport twice - // doesn't create any problem. - SelfSupportBackend.uninit(); -}) diff --git a/browser/modules/test/browser_UnsubmittedCrashHandler.js b/browser/modules/test/browser_UnsubmittedCrashHandler.js deleted file mode 100644 index 2d78c746b..000000000 --- a/browser/modules/test/browser_UnsubmittedCrashHandler.js +++ /dev/null @@ -1,680 +0,0 @@ -"use strict"; - -/** - * This suite tests the "unsubmitted crash report" notification - * that is seen when we detect pending crash reports on startup. - */ - -const { UnsubmittedCrashHandler } = - Cu.import("resource:///modules/ContentCrashHandlers.jsm", this); -const { FileUtils } = - Cu.import("resource://gre/modules/FileUtils.jsm", this); -const { makeFakeAppDir } = - Cu.import("resource://testing-common/AppData.jsm", this); -const { OS } = - Cu.import("resource://gre/modules/osfile.jsm", this); - -const DAY = 24 * 60 * 60 * 1000; // milliseconds -const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs"; - -/** - * Returns the directly where the browsing is storing the - * pending crash reports. - * - * @returns nsIFile - */ -function getPendingCrashReportDir() { - // The fake UAppData directory that makeFakeAppDir provides - // is just UAppData under the profile directory. - return FileUtils.getDir("ProfD", [ - "UAppData", - "Crash Reports", - "pending", - ], false); -} - -/** - * Synchronously deletes all entries inside the pending - * crash report directory. - */ -function clearPendingCrashReports() { - let dir = getPendingCrashReportDir(); - let entries = dir.directoryEntries; - - while (entries.hasMoreElements()) { - let entry = entries.getNext().QueryInterface(Ci.nsIFile); - if (entry.isFile()) { - entry.remove(false); - } - } -} - -/** - * Randomly generates howMany crash report .dmp and .extra files - * to put into the pending crash report directory. We're not - * actually creating real crash reports here, just stubbing - * out enough of the files to satisfy our notification and - * submission code. - * - * @param howMany (int) - * How many pending crash reports to put in the pending - * crash report directory. - * @param accessDate (Date, optional) - * What date to set as the last accessed time on the created - * crash reports. This defaults to the current date and time. - * @returns Promise - */ -function* createPendingCrashReports(howMany, accessDate) { - let dir = getPendingCrashReportDir(); - if (!accessDate) { - accessDate = new Date(); - } - - /** - * Helper function for creating a file in the pending crash report - * directory. - * - * @param fileName (string) - * The filename for the crash report, not including the - * extension. This is usually a UUID. - * @param extension (string) - * The file extension for the created file. - * @param accessDate (Date) - * The date to set lastAccessed to. - * @param contents (string, optional) - * Set this to whatever the file needs to contain, if anything. - * @returns Promise - */ - let createFile = (fileName, extension, accessDate, contents) => { - let file = dir.clone(); - file.append(fileName + "." + extension); - file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); - let promises = [OS.File.setDates(file.path, accessDate)]; - - if (contents) { - let encoder = new TextEncoder(); - let array = encoder.encode(contents); - promises.push(OS.File.writeAtomic(file.path, array, { - tmpPath: file.path + ".tmp", - })); - } - return Promise.all(promises); - } - - let uuidGenerator = Cc["@mozilla.org/uuid-generator;1"] - .getService(Ci.nsIUUIDGenerator); - // CrashSubmit expects there to be a ServerURL key-value - // pair in the .extra file, so we'll satisfy it. - let extraFileContents = "ServerURL=" + SERVER_URL; - - return Task.spawn(function*() { - let uuids = []; - for (let i = 0; i < howMany; ++i) { - let uuid = uuidGenerator.generateUUID().toString(); - // Strip the {}... - uuid = uuid.substring(1, uuid.length - 1); - yield createFile(uuid, "dmp", accessDate); - yield createFile(uuid, "extra", accessDate, extraFileContents); - uuids.push(uuid); - } - return uuids; - }); -} - -/** - * Returns a Promise that resolves once CrashSubmit starts sending - * success notifications for crash submission matching the reportIDs - * being passed in. - * - * @param reportIDs (Array<string>) - * The IDs for the reports that we expect CrashSubmit to have sent. - * @returns Promise - */ -function waitForSubmittedReports(reportIDs) { - let promises = []; - for (let reportID of reportIDs) { - let promise = TestUtils.topicObserved("crash-report-status", (subject, data) => { - if (data == "success") { - let propBag = subject.QueryInterface(Ci.nsIPropertyBag2); - let dumpID = propBag.getPropertyAsAString("minidumpID"); - if (dumpID == reportID) { - return true; - } - } - return false; - }); - promises.push(promise); - } - return Promise.all(promises); -} - -/** - * Returns a Promise that resolves once a .dmp.ignore file is created for - * the crashes in the pending directory matching the reportIDs being - * passed in. - * - * @param reportIDs (Array<string>) - * The IDs for the reports that we expect CrashSubmit to have been - * marked for ignoring. - * @returns Promise - */ -function waitForIgnoredReports(reportIDs) { - let dir = getPendingCrashReportDir(); - let promises = []; - for (let reportID of reportIDs) { - let file = dir.clone(); - file.append(reportID + ".dmp.ignore"); - promises.push(OS.File.exists(file.path)); - } - return Promise.all(promises); -} - -let gNotificationBox; - -add_task(function* setup() { - // Pending crash reports are stored in the UAppData folder, - // which exists outside of the profile folder. In order to - // not overwrite / clear pending crash reports for the poor - // soul who runs this test, we use AppData.jsm to point to - // a special made-up directory inside the profile - // directory. - yield makeFakeAppDir(); - // We'll assume that the notifications will be shown in the current - // browser window's global notification box. - gNotificationBox = document.getElementById("global-notificationbox"); - - // If we happen to already be seeing the unsent crash report - // notification, it's because the developer running this test - // happened to have some unsent reports in their UAppDir. - // We'll remove the notification without touching those reports. - let notification = - gNotificationBox.getNotificationWithValue("pending-crash-reports"); - if (notification) { - notification.close(); - } - - let env = Cc["@mozilla.org/process/environment;1"] - .getService(Components.interfaces.nsIEnvironment); - let oldServerURL = env.get("MOZ_CRASHREPORTER_URL"); - env.set("MOZ_CRASHREPORTER_URL", SERVER_URL); - - // nsBrowserGlue starts up UnsubmittedCrashHandler automatically - // so at this point, it is initialized. It's possible that it - // was initialized, but is preffed off, so it's inert, so we - // shut it down, make sure it's preffed on, and then restart it. - // Note that making the component initialize even when it's - // disabled is an intentional choice, as this allows for easier - // simulation of startup and shutdown. - UnsubmittedCrashHandler.uninit(); - yield SpecialPowers.pushPrefEnv({ - set: [ - ["browser.crashReports.unsubmittedCheck.enabled", true], - ], - }); - UnsubmittedCrashHandler.init(); - - registerCleanupFunction(function() { - gNotificationBox = null; - clearPendingCrashReports(); - env.set("MOZ_CRASHREPORTER_URL", oldServerURL); - }); -}); - -/** - * Tests that if there are no pending crash reports, then the - * notification will not show up. - */ -add_task(function* test_no_pending_no_notification() { - // Make absolutely sure there are no pending crash reports first... - clearPendingCrashReports(); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.equal(notification, null, - "There should not be a notification if there are no " + - "pending crash reports"); -}); - -/** - * Tests that there is a notification if there is one pending - * crash report. - */ -add_task(function* test_one_pending() { - yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - gNotificationBox.removeNotification(notification, true); - clearPendingCrashReports(); -}); - -/** - * Tests that there is a notification if there is more than one - * pending crash report. - */ -add_task(function* test_several_pending() { - yield createPendingCrashReports(3); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - gNotificationBox.removeNotification(notification, true); - clearPendingCrashReports(); -}); - -/** - * Tests that there is no notification if the only pending crash - * reports are over 28 days old. Also checks that if we put a newer - * crash with that older set, that we can still get a notification. - */ -add_task(function* test_several_pending() { - // Let's create some crash reports from 30 days ago. - let oldDate = new Date(Date.now() - (30 * DAY)); - yield createPendingCrashReports(3, oldDate); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.equal(notification, null, - "There should not be a notification if there are only " + - "old pending crash reports"); - // Now let's create a new one and check again - yield createPendingCrashReports(1); - notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - gNotificationBox.removeNotification(notification, true); - clearPendingCrashReports(); -}); - -/** - * Tests that the notification can submit a report. - */ -add_task(function* test_can_submit() { - let reportIDs = yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - // Attempt to submit the notification by clicking on the submit - // button - let buttons = notification.querySelectorAll(".notification-button"); - // ...which should be the first button. - let submit = buttons[0]; - - let promiseReports = waitForSubmittedReports(reportIDs); - info("Sending crash report"); - submit.click(); - info("Sent!"); - // We'll not wait for the notification to finish its transition - - // we'll just remove it right away. - gNotificationBox.removeNotification(notification, true); - - info("Waiting on reports to be received."); - yield promiseReports; - info("Received!"); - clearPendingCrashReports(); -}); - -/** - * Tests that the notification can submit multiple reports. - */ -add_task(function* test_can_submit_several() { - let reportIDs = yield createPendingCrashReports(3); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - // Attempt to submit the notification by clicking on the submit - // button - let buttons = notification.querySelectorAll(".notification-button"); - // ...which should be the first button. - let submit = buttons[0]; - - let promiseReports = waitForSubmittedReports(reportIDs); - info("Sending crash reports"); - submit.click(); - info("Sent!"); - // We'll not wait for the notification to finish its transition - - // we'll just remove it right away. - gNotificationBox.removeNotification(notification, true); - - info("Waiting on reports to be received."); - yield promiseReports; - info("Received!"); - clearPendingCrashReports(); -}); - -/** - * Tests that choosing "Send Always" flips the autoSubmit pref - * and sends the pending crash reports. - */ -add_task(function* test_can_submit_always() { - let pref = "browser.crashReports.unsubmittedCheck.autoSubmit2"; - Assert.equal(Services.prefs.getBoolPref(pref), false, - "We should not be auto-submitting by default"); - - let reportIDs = yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - // Attempt to submit the notification by clicking on the send all - // button - let buttons = notification.querySelectorAll(".notification-button"); - // ...which should be the second button. - let sendAll = buttons[1]; - - let promiseReports = waitForSubmittedReports(reportIDs); - info("Sending crash reports"); - sendAll.click(); - info("Sent!"); - // We'll not wait for the notification to finish its transition - - // we'll just remove it right away. - gNotificationBox.removeNotification(notification, true); - - info("Waiting on reports to be received."); - yield promiseReports; - info("Received!"); - - // Make sure the pref was set - Assert.equal(Services.prefs.getBoolPref(pref), true, - "The autoSubmit pref should have been set"); - - // And revert back to default now. - Services.prefs.clearUserPref(pref); - - clearPendingCrashReports(); -}); - -/** - * Tests that if the user has chosen to automatically send - * crash reports that no notification is displayed to the - * user. - */ -add_task(function* test_can_auto_submit() { - yield SpecialPowers.pushPrefEnv({ set: [ - ["browser.crashReports.unsubmittedCheck.autoSubmit2", true], - ]}); - - let reportIDs = yield createPendingCrashReports(3); - let promiseReports = waitForSubmittedReports(reportIDs); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.equal(notification, null, "There should be no notification"); - info("Waiting on reports to be received."); - yield promiseReports; - info("Received!"); - - clearPendingCrashReports(); - yield SpecialPowers.popPrefEnv(); -}); - -/** - * Tests that if the user chooses to dismiss the notification, - * then the current pending requests won't cause the notification - * to appear again in the future. - */ -add_task(function* test_can_ignore() { - let reportIDs = yield createPendingCrashReports(3); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - // Dismiss the notification by clicking on the "X" button. - let anonyNodes = document.getAnonymousNodes(notification)[0]; - let closeButton = anonyNodes.querySelector(".close-icon"); - closeButton.click(); - // We'll not wait for the notification to finish its transition - - // we'll just remove it right away. - gNotificationBox.removeNotification(notification, true); - yield waitForIgnoredReports(reportIDs); - - notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.equal(notification, null, "There should be no notification"); - - clearPendingCrashReports(); -}); - -/** - * Tests that if the notification is shown, then the - * lastShownDate is set for today. - */ -add_task(function* test_last_shown_date() { - yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - let today = UnsubmittedCrashHandler.dateString(new Date()); - let lastShownDate = - UnsubmittedCrashHandler.prefs.getCharPref("lastShownDate"); - Assert.equal(today, lastShownDate, - "Last shown date should be today."); - - UnsubmittedCrashHandler.prefs.clearUserPref("lastShownDate"); - gNotificationBox.removeNotification(notification, true); - clearPendingCrashReports(); -}); - -/** - * Tests that if UnsubmittedCrashHandler is uninit with a - * notification still being shown, that - * browser.crashReports.unsubmittedCheck.shutdownWhileShowing is - * set to true. - */ -add_task(function* test_shutdown_while_showing() { - yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - UnsubmittedCrashHandler.uninit(); - let shutdownWhileShowing = - UnsubmittedCrashHandler.prefs.getBoolPref("shutdownWhileShowing"); - Assert.ok(shutdownWhileShowing, - "We should have noticed that we uninitted while showing " + - "the notification."); - UnsubmittedCrashHandler.prefs.clearUserPref("shutdownWhileShowing"); - UnsubmittedCrashHandler.init(); - - gNotificationBox.removeNotification(notification, true); - clearPendingCrashReports(); -}); - -/** - * Tests that if UnsubmittedCrashHandler is uninit after - * the notification has been closed, that - * browser.crashReports.unsubmittedCheck.shutdownWhileShowing is - * not set in prefs. - */ -add_task(function* test_shutdown_while_not_showing() { - let reportIDs = yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - // Dismiss the notification by clicking on the "X" button. - let anonyNodes = document.getAnonymousNodes(notification)[0]; - let closeButton = anonyNodes.querySelector(".close-icon"); - closeButton.click(); - // We'll not wait for the notification to finish its transition - - // we'll just remove it right away. - gNotificationBox.removeNotification(notification, true); - - yield waitForIgnoredReports(reportIDs); - - UnsubmittedCrashHandler.uninit(); - Assert.throws(() => { - UnsubmittedCrashHandler.prefs.getBoolPref("shutdownWhileShowing"); - }, "We should have noticed that the notification had closed before " + - "uninitting."); - UnsubmittedCrashHandler.init(); - - clearPendingCrashReports(); -}); - -/** - * Tests that if - * browser.crashReports.unsubmittedCheck.shutdownWhileShowing is - * set and the lastShownDate is today, then we don't decrement - * browser.crashReports.unsubmittedCheck.chancesUntilSuppress. - */ -add_task(function* test_dont_decrement_chances_on_same_day() { - let initChances = - UnsubmittedCrashHandler.prefs.getIntPref("chancesUntilSuppress"); - Assert.ok(initChances > 1, "We should start with at least 1 chance."); - - yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - UnsubmittedCrashHandler.uninit(); - - gNotificationBox.removeNotification(notification, true); - - let shutdownWhileShowing = - UnsubmittedCrashHandler.prefs.getBoolPref("shutdownWhileShowing"); - Assert.ok(shutdownWhileShowing, - "We should have noticed that we uninitted while showing " + - "the notification."); - - let today = UnsubmittedCrashHandler.dateString(new Date()); - let lastShownDate = - UnsubmittedCrashHandler.prefs.getCharPref("lastShownDate"); - Assert.equal(today, lastShownDate, - "Last shown date should be today."); - - UnsubmittedCrashHandler.init(); - - notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should still be a notification"); - - let chances = - UnsubmittedCrashHandler.prefs.getIntPref("chancesUntilSuppress"); - - Assert.equal(initChances, chances, - "We should not have decremented chances."); - - gNotificationBox.removeNotification(notification, true); - clearPendingCrashReports(); -}); - -/** - * Tests that if - * browser.crashReports.unsubmittedCheck.shutdownWhileShowing is - * set and the lastShownDate is before today, then we decrement - * browser.crashReports.unsubmittedCheck.chancesUntilSuppress. - */ -add_task(function* test_decrement_chances_on_other_day() { - let initChances = - UnsubmittedCrashHandler.prefs.getIntPref("chancesUntilSuppress"); - Assert.ok(initChances > 1, "We should start with at least 1 chance."); - - yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should be a notification"); - - UnsubmittedCrashHandler.uninit(); - - gNotificationBox.removeNotification(notification, true); - - let shutdownWhileShowing = - UnsubmittedCrashHandler.prefs.getBoolPref("shutdownWhileShowing"); - Assert.ok(shutdownWhileShowing, - "We should have noticed that we uninitted while showing " + - "the notification."); - - // Now pretend that the notification was shown yesterday. - let yesterday = UnsubmittedCrashHandler.dateString(new Date(Date.now() - DAY)); - UnsubmittedCrashHandler.prefs.setCharPref("lastShownDate", yesterday); - - UnsubmittedCrashHandler.init(); - - notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.ok(notification, "There should still be a notification"); - - let chances = - UnsubmittedCrashHandler.prefs.getIntPref("chancesUntilSuppress"); - - Assert.equal(initChances - 1, chances, - "We should have decremented our chances."); - UnsubmittedCrashHandler.prefs.clearUserPref("chancesUntilSuppress"); - - gNotificationBox.removeNotification(notification, true); - clearPendingCrashReports(); -}); - -/** - * Tests that if we've shutdown too many times showing the - * notification, and we've run out of chances, then - * browser.crashReports.unsubmittedCheck.suppressUntilDate is - * set for some days into the future. - */ -add_task(function* test_can_suppress_after_chances() { - // Pretend that a notification was shown yesterday. - let yesterday = UnsubmittedCrashHandler.dateString(new Date(Date.now() - DAY)); - UnsubmittedCrashHandler.prefs.setCharPref("lastShownDate", yesterday); - UnsubmittedCrashHandler.prefs.setBoolPref("shutdownWhileShowing", true); - UnsubmittedCrashHandler.prefs.setIntPref("chancesUntilSuppress", 0); - - yield createPendingCrashReports(1); - let notification = - yield UnsubmittedCrashHandler.checkForUnsubmittedCrashReports(); - Assert.equal(notification, null, - "There should be no notification if we've run out of chances"); - - // We should have set suppressUntilDate into the future - let suppressUntilDate = - UnsubmittedCrashHandler.prefs.getCharPref("suppressUntilDate"); - - let today = UnsubmittedCrashHandler.dateString(new Date()); - Assert.ok(suppressUntilDate > today, - "We should be suppressing until some days into the future."); - - UnsubmittedCrashHandler.prefs.clearUserPref("chancesUntilSuppress"); - UnsubmittedCrashHandler.prefs.clearUserPref("suppressUntilDate"); - UnsubmittedCrashHandler.prefs.clearUserPref("lastShownDate"); - clearPendingCrashReports(); -}); - -/** - * Tests that if there's a suppression date set, then no notification - * will be shown even if there are pending crash reports. - */ -add_task(function* test_suppression() { - let future = UnsubmittedCrashHandler.dateString(new Date(Date.now() + (DAY * 5))); - UnsubmittedCrashHandler.prefs.setCharPref("suppressUntilDate", future); - UnsubmittedCrashHandler.uninit(); - UnsubmittedCrashHandler.init(); - - Assert.ok(UnsubmittedCrashHandler.suppressed, - "The UnsubmittedCrashHandler should be suppressed."); - UnsubmittedCrashHandler.prefs.clearUserPref("suppressUntilDate"); - - UnsubmittedCrashHandler.uninit(); - UnsubmittedCrashHandler.init(); -}); - -/** - * Tests that if there's a suppression date set, but we've exceeded - * it, then we can show the notification again. - */ -add_task(function* test_end_suppression() { - let yesterday = UnsubmittedCrashHandler.dateString(new Date(Date.now() - DAY)); - UnsubmittedCrashHandler.prefs.setCharPref("suppressUntilDate", yesterday); - UnsubmittedCrashHandler.uninit(); - UnsubmittedCrashHandler.init(); - - Assert.ok(!UnsubmittedCrashHandler.suppressed, - "The UnsubmittedCrashHandler should not be suppressed."); - Assert.ok(!UnsubmittedCrashHandler.prefs.prefHasUserValue("suppressUntilDate"), - "The suppression date should been cleared from preferences."); - - UnsubmittedCrashHandler.uninit(); - UnsubmittedCrashHandler.init(); -}); diff --git a/browser/modules/test/browser_UsageTelemetry.js b/browser/modules/test/browser_UsageTelemetry.js deleted file mode 100644 index a84f33a97..000000000 --- a/browser/modules/test/browser_UsageTelemetry.js +++ /dev/null @@ -1,268 +0,0 @@ -"use strict"; - -const MAX_CONCURRENT_TABS = "browser.engagement.max_concurrent_tab_count"; -const TAB_EVENT_COUNT = "browser.engagement.tab_open_event_count"; -const MAX_CONCURRENT_WINDOWS = "browser.engagement.max_concurrent_window_count"; -const WINDOW_OPEN_COUNT = "browser.engagement.window_open_event_count"; -const TOTAL_URI_COUNT = "browser.engagement.total_uri_count"; -const UNIQUE_DOMAINS_COUNT = "browser.engagement.unique_domains_count"; -const UNFILTERED_URI_COUNT = "browser.engagement.unfiltered_uri_count"; - -const TELEMETRY_SUBSESSION_TOPIC = "internal-telemetry-after-subsession-split"; - -/** - * Waits for the web progress listener associated with this tab to fire an - * onLocationChange for a non-error page. - * - * @param {xul:browser} browser - * A xul:browser. - * - * @return {Promise} - * @resolves When navigating to a non-error page. - */ -function browserLocationChanged(browser) { - return new Promise(resolve => { - let wpl = { - onStateChange() {}, - onSecurityChange() {}, - onStatusChange() {}, - onLocationChange(aWebProgress, aRequest, aURI, aFlags) { - if (!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE)) { - browser.webProgress.removeProgressListener(filter); - filter.removeProgressListener(wpl); - resolve(); - } - }, - QueryInterface: XPCOMUtils.generateQI([ - Ci.nsIWebProgressListener, - Ci.nsIWebProgressListener2, - ]), - }; - const filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"] - .createInstance(Ci.nsIWebProgress); - filter.addProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL); - browser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL); - }); -} - -/** - * An helper that checks the value of a scalar if it's expected to be > 0, - * otherwise makes sure that the scalar it's not reported. - */ -let checkScalar = (scalars, scalarName, value, msg) => { - if (value > 0) { - is(scalars[scalarName], value, msg); - return; - } - ok(!(scalarName in scalars), scalarName + " must not be reported."); -}; - -/** - * Get a snapshot of the scalars and check them against the provided values. - */ -let checkScalars = (countsObject) => { - const scalars = - Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN); - - // Check the expected values. Scalars that are never set must not be reported. - checkScalar(scalars, MAX_CONCURRENT_TABS, countsObject.maxTabs, - "The maximum tab count must match the expected value."); - checkScalar(scalars, TAB_EVENT_COUNT, countsObject.tabOpenCount, - "The number of open tab event count must match the expected value."); - checkScalar(scalars, MAX_CONCURRENT_WINDOWS, countsObject.maxWindows, - "The maximum window count must match the expected value."); - checkScalar(scalars, WINDOW_OPEN_COUNT, countsObject.windowsOpenCount, - "The number of window open event count must match the expected value."); - checkScalar(scalars, TOTAL_URI_COUNT, countsObject.totalURIs, - "The total URI count must match the expected value."); - checkScalar(scalars, UNIQUE_DOMAINS_COUNT, countsObject.domainCount, - "The unique domains count must match the expected value."); - checkScalar(scalars, UNFILTERED_URI_COUNT, countsObject.totalUnfilteredURIs, - "The unfiltered URI count must match the expected value."); -}; - -add_task(function* test_tabsAndWindows() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - - let openedTabs = []; - let expectedTabOpenCount = 0; - let expectedWinOpenCount = 0; - let expectedMaxTabs = 0; - let expectedMaxWins = 0; - - // Add a new tab and check that the count is right. - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank")); - expectedTabOpenCount = 1; - expectedMaxTabs = 2; - // This, and all the checks below, also check that initial pages (about:newtab, about:blank, ..) - // are not counted by the total_uri_count and the unfiltered_uri_count probes. - checkScalars({maxTabs: expectedMaxTabs, tabOpenCount: expectedTabOpenCount, maxWindows: expectedMaxWins, - windowsOpenCount: expectedWinOpenCount, totalURIs: 0, domainCount: 0, - totalUnfilteredURIs: 0}); - - // Add two new tabs in the same window. - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank")); - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank")); - expectedTabOpenCount += 2; - expectedMaxTabs += 2; - checkScalars({maxTabs: expectedMaxTabs, tabOpenCount: expectedTabOpenCount, maxWindows: expectedMaxWins, - windowsOpenCount: expectedWinOpenCount, totalURIs: 0, domainCount: 0, - totalUnfilteredURIs: 0}); - - // Add a new window and then some tabs in it. An empty new windows counts as a tab. - let win = yield BrowserTestUtils.openNewBrowserWindow(); - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank")); - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank")); - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank")); - // The new window started with a new tab, so account for it. - expectedTabOpenCount += 4; - expectedWinOpenCount += 1; - expectedMaxWins = 2; - expectedMaxTabs += 4; - - // Remove a tab from the first window, the max shouldn't change. - yield BrowserTestUtils.removeTab(openedTabs.pop()); - checkScalars({maxTabs: expectedMaxTabs, tabOpenCount: expectedTabOpenCount, maxWindows: expectedMaxWins, - windowsOpenCount: expectedWinOpenCount, totalURIs: 0, domainCount: 0, - totalUnfilteredURIs: 0}); - - // Remove all the extra windows and tabs. - for (let tab of openedTabs) { - yield BrowserTestUtils.removeTab(tab); - } - yield BrowserTestUtils.closeWindow(win); - - // Make sure all the scalars still have the expected values. - checkScalars({maxTabs: expectedMaxTabs, tabOpenCount: expectedTabOpenCount, maxWindows: expectedMaxWins, - windowsOpenCount: expectedWinOpenCount, totalURIs: 0, domainCount: 0, - totalUnfilteredURIs: 0}); -}); - -add_task(function* test_subsessionSplit() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - - // Add a new window (that will have 4 tabs). - let win = yield BrowserTestUtils.openNewBrowserWindow(); - let openedTabs = []; - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:blank")); - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "about:mozilla")); - openedTabs.push(yield BrowserTestUtils.openNewForegroundTab(win.gBrowser, "http://www.example.com")); - - // Check that the scalars have the right values. We expect 2 unfiltered URI loads - // (about:mozilla and www.example.com, but no about:blank) and 1 URI totalURIs - // (only www.example.com). - checkScalars({maxTabs: 5, tabOpenCount: 4, maxWindows: 2, windowsOpenCount: 1, - totalURIs: 1, domainCount: 1, totalUnfilteredURIs: 2}); - - // Remove a tab. - yield BrowserTestUtils.removeTab(openedTabs.pop()); - - // Simulate a subsession split by clearing the scalars (via |snapshotScalars|) and - // notifying the subsession split topic. - Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, - true /* clearScalars */); - Services.obs.notifyObservers(null, TELEMETRY_SUBSESSION_TOPIC, ""); - - // After a subsession split, only the MAX_CONCURRENT_* scalars must be available - // and have the correct value. No tabs, windows or URIs were opened so other scalars - // must not be reported. - checkScalars({maxTabs: 4, tabOpenCount: 0, maxWindows: 2, windowsOpenCount: 0, - totalURIs: 0, domainCount: 0, totalUnfilteredURIs: 0}); - - // Remove all the extra windows and tabs. - for (let tab of openedTabs) { - yield BrowserTestUtils.removeTab(tab); - } - yield BrowserTestUtils.closeWindow(win); -}); - -add_task(function* test_URIAndDomainCounts() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - - let checkCounts = (countsObject) => { - // Get a snapshot of the scalars and then clear them. - const scalars = - Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN); - checkScalar(scalars, TOTAL_URI_COUNT, countsObject.totalURIs, - "The URI scalar must contain the expected value."); - checkScalar(scalars, UNIQUE_DOMAINS_COUNT, countsObject.domainCount, - "The unique domains scalar must contain the expected value."); - checkScalar(scalars, UNFILTERED_URI_COUNT, countsObject.totalUnfilteredURIs, - "The unfiltered URI scalar must contain the expected value."); - }; - - // Check that about:blank doesn't get counted in the URI total. - let firstTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - checkCounts({totalURIs: 0, domainCount: 0, totalUnfilteredURIs: 0}); - - // Open a different page and check the counts. - yield BrowserTestUtils.loadURI(firstTab.linkedBrowser, "http://example.com/"); - yield BrowserTestUtils.browserLoaded(firstTab.linkedBrowser); - checkCounts({totalURIs: 1, domainCount: 1, totalUnfilteredURIs: 1}); - - // Activating a different tab must not increase the URI count. - let secondTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - yield BrowserTestUtils.switchTab(gBrowser, firstTab); - checkCounts({totalURIs: 1, domainCount: 1, totalUnfilteredURIs: 1}); - yield BrowserTestUtils.removeTab(secondTab); - - // Open a new window and set the tab to a new address. - let newWin = yield BrowserTestUtils.openNewBrowserWindow(); - yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://example.com/"); - yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser); - checkCounts({totalURIs: 2, domainCount: 1, totalUnfilteredURIs: 2}); - - // We should not count AJAX requests. - const XHR_URL = "http://example.com/r"; - yield ContentTask.spawn(newWin.gBrowser.selectedBrowser, XHR_URL, function(url) { - return new Promise(resolve => { - var xhr = new content.window.XMLHttpRequest(); - xhr.open("GET", url); - xhr.onload = () => resolve(); - xhr.send(); - }); - }); - checkCounts({totalURIs: 2, domainCount: 1, totalUnfilteredURIs: 2}); - - // Check that we're counting page fragments. - let loadingStopped = browserLocationChanged(newWin.gBrowser.selectedBrowser); - yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://example.com/#2"); - yield loadingStopped; - checkCounts({totalURIs: 3, domainCount: 1, totalUnfilteredURIs: 3}); - - // Check that a different URI from the example.com domain doesn't increment the unique count. - yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "http://test1.example.com/"); - yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser); - checkCounts({totalURIs: 4, domainCount: 1, totalUnfilteredURIs: 4}); - - // Make sure that the unique domains counter is incrementing for a different domain. - yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, "https://example.org/"); - yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser); - checkCounts({totalURIs: 5, domainCount: 2, totalUnfilteredURIs: 5}); - - // Check that we only account for top level loads (e.g. we don't count URIs from - // embedded iframes). - yield ContentTask.spawn(newWin.gBrowser.selectedBrowser, null, function* () { - let doc = content.document; - let iframe = doc.createElement("iframe"); - let promiseIframeLoaded = ContentTaskUtils.waitForEvent(iframe, "load", false); - iframe.src = "https://example.org/test"; - doc.body.insertBefore(iframe, doc.body.firstChild); - yield promiseIframeLoaded; - }); - checkCounts({totalURIs: 5, domainCount: 2, totalUnfilteredURIs: 5}); - - // Check that uncommon protocols get counted in the unfiltered URI probe. - const TEST_PAGE = - "data:text/html,<a id='target' href='%23par1'>Click me</a><a name='par1'>The paragraph.</a>"; - yield BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, TEST_PAGE); - yield BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser); - checkCounts({totalURIs: 5, domainCount: 2, totalUnfilteredURIs: 6}); - - // Clean up. - yield BrowserTestUtils.removeTab(firstTab); - yield BrowserTestUtils.closeWindow(newWin); -}); diff --git a/browser/modules/test/browser_UsageTelemetry_content.js b/browser/modules/test/browser_UsageTelemetry_content.js deleted file mode 100644 index 35c6b5a6d..000000000 --- a/browser/modules/test/browser_UsageTelemetry_content.js +++ /dev/null @@ -1,121 +0,0 @@ -"use strict"; - -const BASE_PROBE_NAME = "browser.engagement.navigation."; -const SCALAR_CONTEXT_MENU = BASE_PROBE_NAME + "contextmenu"; -const SCALAR_ABOUT_NEWTAB = BASE_PROBE_NAME + "about_newtab"; - -add_task(function* setup() { - // Create two new search engines. Mark one as the default engine, so - // the test don't crash. We need to engines for this test as the searchbar - // in content doesn't display the default search engine among the one-off engines. - Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET", - "http://example.com/?q={searchTerms}"); - - Services.search.addEngineWithDetails("MozSearch2", "", "mozalias2", "", "GET", - "http://example.com/?q={searchTerms}"); - - // Make the first engine the default search engine. - let engineDefault = Services.search.getEngineByName("MozSearch"); - let originalEngine = Services.search.currentEngine; - Services.search.currentEngine = engineDefault; - - // Move the second engine at the beginning of the one-off list. - let engineOneOff = Services.search.getEngineByName("MozSearch2"); - Services.search.moveEngine(engineOneOff, 0); - - yield SpecialPowers.pushPrefEnv({"set": [ - ["dom.select_events.enabled", true], // We want select events to be fired. - ["toolkit.telemetry.enabled", true] // And Extended Telemetry to be enabled. - ]}); - - // Make sure to restore the engine once we're done. - registerCleanupFunction(function* () { - Services.search.currentEngine = originalEngine; - Services.search.removeEngine(engineDefault); - Services.search.removeEngine(engineOneOff); - }); -}); - -add_task(function* test_context_menu() { - // Let's reset the Telemetry data. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - // Open a new tab with a page containing some text. - let tab = - yield BrowserTestUtils.openNewForegroundTab(gBrowser, "data:text/plain;charset=utf8,test%20search"); - - info("Select all the text in the page."); - yield ContentTask.spawn(tab.linkedBrowser, "", function*() { - return new Promise(resolve => { - content.document.addEventListener("selectionchange", () => resolve(), { once: true }); - content.document.getSelection().selectAllChildren(content.document.body); - }); - }); - - info("Open the context menu."); - let contextMenu = document.getElementById("contentAreaContextMenu"); - let popupPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown"); - BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, - gBrowser.selectedBrowser); - yield popupPromise; - - info("Click on search."); - let searchItem = contextMenu.getElementsByAttribute("id", "context-searchselect")[0]; - searchItem.click(); - - info("Validate the search metrics."); - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_CONTEXT_MENU, "search", 1); - Assert.equal(Object.keys(scalars[SCALAR_CONTEXT_MENU]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - checkKeyedHistogram(search_hist, 'other-MozSearch.contextmenu', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "contextmenu", null, {engine: "other-MozSearch"}]]); - - contextMenu.hidePopup(); - yield BrowserTestUtils.removeTab(gBrowser.selectedTab); - yield BrowserTestUtils.removeTab(tab); -}); - -add_task(function* test_about_newtab() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:newtab", false); - yield ContentTask.spawn(tab.linkedBrowser, null, function* () { - yield ContentTaskUtils.waitForCondition(() => !content.document.hidden); - }); - - info("Trigger a simple serch, just text + enter."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield typeInSearchField(tab.linkedBrowser, "test query", "newtab-search-text"); - yield BrowserTestUtils.synthesizeKey("VK_RETURN", {}, tab.linkedBrowser); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_ABOUT_NEWTAB, "search_enter", 1); - Assert.equal(Object.keys(scalars[SCALAR_ABOUT_NEWTAB]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - checkKeyedHistogram(search_hist, 'other-MozSearch.newtab', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "about_newtab", "enter", {engine: "other-MozSearch"}]]); - - yield BrowserTestUtils.removeTab(tab); -}); diff --git a/browser/modules/test/browser_UsageTelemetry_content_aboutHome.js b/browser/modules/test/browser_UsageTelemetry_content_aboutHome.js deleted file mode 100644 index 1818ae5fd..000000000 --- a/browser/modules/test/browser_UsageTelemetry_content_aboutHome.js +++ /dev/null @@ -1,84 +0,0 @@ -"use strict"; - -const SCALAR_ABOUT_HOME = "browser.engagement.navigation.about_home"; - -add_task(function* setup() { - // about:home uses IndexedDB. However, the test finishes too quickly and doesn't - // allow it enougth time to save. So it throws. This disables all the uncaught - // exception in this file and that's the reason why we split about:home tests - // out of the other UsageTelemetry files. - ignoreAllUncaughtExceptions(); - - // Create two new search engines. Mark one as the default engine, so - // the test don't crash. We need to engines for this test as the searchbar - // in content doesn't display the default search engine among the one-off engines. - Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET", - "http://example.com/?q={searchTerms}"); - - Services.search.addEngineWithDetails("MozSearch2", "", "mozalias2", "", "GET", - "http://example.com/?q={searchTerms}"); - - // Make the first engine the default search engine. - let engineDefault = Services.search.getEngineByName("MozSearch"); - let originalEngine = Services.search.currentEngine; - Services.search.currentEngine = engineDefault; - - // Move the second engine at the beginning of the one-off list. - let engineOneOff = Services.search.getEngineByName("MozSearch2"); - Services.search.moveEngine(engineOneOff, 0); - - // Enable Extended Telemetry. - yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]}); - - // Make sure to restore the engine once we're done. - registerCleanupFunction(function* () { - Services.search.currentEngine = originalEngine; - Services.search.removeEngine(engineDefault); - Services.search.removeEngine(engineOneOff); - }); -}); - -add_task(function* test_abouthome_simpleQuery() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser); - - info("Setup waiting for AboutHomeLoadSnippetsCompleted."); - let promiseAboutHomeLoaded = new Promise(resolve => { - tab.linkedBrowser.addEventListener("AboutHomeLoadSnippetsCompleted", function loadListener(event) { - tab.linkedBrowser.removeEventListener("AboutHomeLoadSnippetsCompleted", loadListener, true); - resolve(); - }, true, true); - }); - - info("Load about:home."); - tab.linkedBrowser.loadURI("about:home"); - info("Wait for AboutHomeLoadSnippetsCompleted."); - yield promiseAboutHomeLoaded; - - info("Trigger a simple serch, just test + enter."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield typeInSearchField(tab.linkedBrowser, "test query", "searchText"); - yield BrowserTestUtils.synthesizeKey("VK_RETURN", {}, tab.linkedBrowser); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_ABOUT_HOME, "search_enter", 1); - Assert.equal(Object.keys(scalars[SCALAR_ABOUT_HOME]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - checkKeyedHistogram(search_hist, 'other-MozSearch.abouthome', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "about_home", "enter", {engine: "other-MozSearch"}]]); - - yield BrowserTestUtils.removeTab(tab); -}); diff --git a/browser/modules/test/browser_UsageTelemetry_private_and_restore.js b/browser/modules/test/browser_UsageTelemetry_private_and_restore.js deleted file mode 100644 index 144a4a03f..000000000 --- a/browser/modules/test/browser_UsageTelemetry_private_and_restore.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; - -const MAX_CONCURRENT_TABS = "browser.engagement.max_concurrent_tab_count"; -const TAB_EVENT_COUNT = "browser.engagement.tab_open_event_count"; -const MAX_CONCURRENT_WINDOWS = "browser.engagement.max_concurrent_window_count"; -const WINDOW_OPEN_COUNT = "browser.engagement.window_open_event_count"; -const TOTAL_URI_COUNT = "browser.engagement.total_uri_count"; -const UNFILTERED_URI_COUNT = "browser.engagement.unfiltered_uri_count"; -const UNIQUE_DOMAINS_COUNT = "browser.engagement.unique_domains_count"; - -function promiseBrowserStateRestored() { - return new Promise(resolve => { - Services.obs.addObserver(function observer(aSubject, aTopic) { - Services.obs.removeObserver(observer, "sessionstore-browser-state-restored"); - resolve(); - }, "sessionstore-browser-state-restored", false); - }); -} - -add_task(function* test_privateMode() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - - // Open a private window and load a website in it. - let privateWin = yield BrowserTestUtils.openNewBrowserWindow({private: true}); - yield BrowserTestUtils.loadURI(privateWin.gBrowser.selectedBrowser, "http://example.com/"); - yield BrowserTestUtils.browserLoaded(privateWin.gBrowser.selectedBrowser); - - // Check that tab and window count is recorded. - const scalars = - Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN); - - ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs in private mode."); - ok(!(UNFILTERED_URI_COUNT in scalars), "We should not track URIs in private mode."); - ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains in private mode."); - is(scalars[TAB_EVENT_COUNT], 1, "The number of open tab event count must match the expected value."); - is(scalars[MAX_CONCURRENT_TABS], 2, "The maximum tab count must match the expected value."); - is(scalars[WINDOW_OPEN_COUNT], 1, "The number of window open event count must match the expected value."); - is(scalars[MAX_CONCURRENT_WINDOWS], 2, "The maximum window count must match the expected value."); - - // Clean up. - yield BrowserTestUtils.closeWindow(privateWin); -}); - -add_task(function* test_sessionRestore() { - const PREF_RESTORE_ON_DEMAND = "browser.sessionstore.restore_on_demand"; - Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false); - registerCleanupFunction(() => { - Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND); - }); - - // Let's reset the counts. - Services.telemetry.clearScalars(); - - // The first window will be put into the already open window and the second - // window will be opened with _openWindowWithState, which is the source of the problem. - const state = { - windows: [ - { - tabs: [ - { entries: [{ url: "http://example.org" }], extData: { "uniq": 3785 } } - ], - selected: 1 - } - ] - }; - - // Save the current session. - let SessionStore = - Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStore; - - // Load the custom state and wait for SSTabRestored, as we want to make sure - // that the URI counting code was hit. - let tabRestored = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "SSTabRestored"); - SessionStore.setBrowserState(JSON.stringify(state)); - yield tabRestored; - - // Check that the URI is not recorded. - const scalars = - Services.telemetry.snapshotScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN); - - ok(!(TOTAL_URI_COUNT in scalars), "We should not track URIs from restored sessions."); - ok(!(UNFILTERED_URI_COUNT in scalars), "We should not track URIs from restored sessions."); - ok(!(UNIQUE_DOMAINS_COUNT in scalars), "We should not track unique domains from restored sessions."); - - // Restore the original session and cleanup. - let sessionRestored = promiseBrowserStateRestored(); - SessionStore.setBrowserState(JSON.stringify(state)); - yield sessionRestored; -}); diff --git a/browser/modules/test/browser_UsageTelemetry_searchbar.js b/browser/modules/test/browser_UsageTelemetry_searchbar.js deleted file mode 100644 index 8aa3ceaee..000000000 --- a/browser/modules/test/browser_UsageTelemetry_searchbar.js +++ /dev/null @@ -1,195 +0,0 @@ -"use strict"; - -const SCALAR_SEARCHBAR = "browser.engagement.navigation.searchbar"; - -let searchInSearchbar = Task.async(function* (inputText) { - let win = window; - yield new Promise(r => waitForFocus(r, win)); - let sb = BrowserSearch.searchBar; - // Write the search query in the searchbar. - sb.focus(); - sb.value = inputText; - sb.textbox.controller.startSearch(inputText); - // Wait for the popup to show. - yield BrowserTestUtils.waitForEvent(sb.textbox.popup, "popupshown"); - // And then for the search to complete. - yield BrowserTestUtils.waitForCondition(() => sb.textbox.controller.searchStatus >= - Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH, - "The search in the searchbar must complete."); -}); - -/** - * Click one of the entries in the search suggestion popup. - * - * @param {String} entryName - * The name of the elemet to click on. - */ -function clickSearchbarSuggestion(entryName) { - let popup = BrowserSearch.searchBar.textbox.popup; - let column = popup.tree.columns[0]; - - for (let rowID = 0; rowID < popup.tree.view.rowCount; rowID++) { - const suggestion = popup.tree.view.getValueAt(rowID, column); - if (suggestion !== entryName) { - continue; - } - - // Make sure the suggestion is visible, just in case. - let tbo = popup.tree.treeBoxObject; - tbo.ensureRowIsVisible(rowID); - // Calculate the click coordinates. - let rect = tbo.getCoordsForCellItem(rowID, column, "text"); - let x = rect.x + rect.width / 2; - let y = rect.y + rect.height / 2; - // Simulate the click. - EventUtils.synthesizeMouse(popup.tree.body, x, y, {}, - popup.tree.ownerGlobal); - break; - } -} - -add_task(function* setup() { - // Create two new search engines. Mark one as the default engine, so - // the test don't crash. We need to engines for this test as the searchbar - // doesn't display the default search engine among the one-off engines. - Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET", - "http://example.com/?q={searchTerms}"); - - Services.search.addEngineWithDetails("MozSearch2", "", "mozalias2", "", "GET", - "http://example.com/?q={searchTerms}"); - - // Make the first engine the default search engine. - let engineDefault = Services.search.getEngineByName("MozSearch"); - let originalEngine = Services.search.currentEngine; - Services.search.currentEngine = engineDefault; - - // Move the second engine at the beginning of the one-off list. - let engineOneOff = Services.search.getEngineByName("MozSearch2"); - Services.search.moveEngine(engineOneOff, 0); - - // Enable Extended Telemetry. - yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]}); - - // Make sure to restore the engine once we're done. - registerCleanupFunction(function* () { - Services.search.currentEngine = originalEngine; - Services.search.removeEngine(engineDefault); - Services.search.removeEngine(engineOneOff); - }); -}); - -add_task(function* test_plainQuery() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - - info("Simulate entering a simple search."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield searchInSearchbar("simple query"); - EventUtils.sendKey("return"); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_SEARCHBAR, "search_enter", 1); - Assert.equal(Object.keys(scalars[SCALAR_SEARCHBAR]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - checkKeyedHistogram(search_hist, 'other-MozSearch.searchbar', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "searchbar", "enter", {engine: "other-MozSearch"}]]); - - yield BrowserTestUtils.removeTab(tab); -}); - -add_task(function* test_oneOff() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - - info("Perform a one-off search using the first engine."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield searchInSearchbar("query"); - - info("Pressing Alt+Down to highlight the first one off engine."); - EventUtils.synthesizeKey("VK_DOWN", { altKey: true }); - EventUtils.sendKey("return"); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_SEARCHBAR, "search_oneoff", 1); - Assert.equal(Object.keys(scalars[SCALAR_SEARCHBAR]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - checkKeyedHistogram(search_hist, 'other-MozSearch2.searchbar', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "searchbar", "oneoff", {engine: "other-MozSearch2"}]]); - - yield BrowserTestUtils.removeTab(tab); -}); - -add_task(function* test_suggestion() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - // Create an engine to generate search suggestions and add it as default - // for this test. - const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml"; - let suggestionEngine = yield new Promise((resolve, reject) => { - Services.search.addEngine(url, null, "", false, { - onSuccess(engine) { resolve(engine) }, - onError() { reject() } - }); - }); - - let previousEngine = Services.search.currentEngine; - Services.search.currentEngine = suggestionEngine; - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - - info("Perform a one-off search using the first engine."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield searchInSearchbar("query"); - info("Clicking the searchbar suggestion."); - clickSearchbarSuggestion("queryfoo"); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_SEARCHBAR, "search_suggestion", 1); - Assert.equal(Object.keys(scalars[SCALAR_SEARCHBAR]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - let searchEngineId = 'other-' + suggestionEngine.name; - checkKeyedHistogram(search_hist, searchEngineId + '.searchbar', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "searchbar", "suggestion", {engine: searchEngineId}]]); - - Services.search.currentEngine = previousEngine; - Services.search.removeEngine(suggestionEngine); - yield BrowserTestUtils.removeTab(tab); -}); diff --git a/browser/modules/test/browser_UsageTelemetry_urlbar.js b/browser/modules/test/browser_UsageTelemetry_urlbar.js deleted file mode 100644 index 81d3e28ba..000000000 --- a/browser/modules/test/browser_UsageTelemetry_urlbar.js +++ /dev/null @@ -1,220 +0,0 @@ -"use strict"; - -const SCALAR_URLBAR = "browser.engagement.navigation.urlbar"; - -// The preference to enable suggestions in the urlbar. -const SUGGEST_URLBAR_PREF = "browser.urlbar.suggest.searches"; -// The name of the search engine used to generate suggestions. -const SUGGESTION_ENGINE_NAME = "browser_UsageTelemetry usageTelemetrySearchSuggestions.xml"; -const ONEOFF_URLBAR_PREF = "browser.urlbar.oneOffSearches"; - -let searchInAwesomebar = Task.async(function* (inputText, win=window) { - yield new Promise(r => waitForFocus(r, win)); - // Write the search query in the urlbar. - win.gURLBar.focus(); - win.gURLBar.value = inputText; - win.gURLBar.controller.startSearch(inputText); - // Wait for the popup to show. - yield BrowserTestUtils.waitForEvent(win.gURLBar.popup, "popupshown"); - // And then for the search to complete. - yield BrowserTestUtils.waitForCondition(() => win.gURLBar.controller.searchStatus >= - Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH); -}); - -/** - * Click one of the entries in the urlbar suggestion popup. - * - * @param {String} entryName - * The name of the elemet to click on. - */ -function clickURLBarSuggestion(entryName) { - // The entry in the suggestion list should follow the format: - // "<search term> <engine name> Search" - const expectedSuggestionName = entryName + " " + SUGGESTION_ENGINE_NAME + " Search"; - for (let child of gURLBar.popup.richlistbox.children) { - if (child.label === expectedSuggestionName) { - // This entry is the search suggestion we're looking for. - child.click(); - return; - } - } -} - -add_task(function* setup() { - // Create a new search engine. - Services.search.addEngineWithDetails("MozSearch", "", "mozalias", "", "GET", - "http://example.com/?q={searchTerms}"); - - // Make it the default search engine. - let engine = Services.search.getEngineByName("MozSearch"); - let originalEngine = Services.search.currentEngine; - Services.search.currentEngine = engine; - - // And the first one-off engine. - Services.search.moveEngine(engine, 0); - - // Enable search suggestions in the urlbar. - Services.prefs.setBoolPref(SUGGEST_URLBAR_PREF, true); - - // Enable the urlbar one-off buttons. - Services.prefs.setBoolPref(ONEOFF_URLBAR_PREF, true); - - // Enable Extended Telemetry. - yield SpecialPowers.pushPrefEnv({"set": [["toolkit.telemetry.enabled", true]]}); - - // Make sure to restore the engine once we're done. - registerCleanupFunction(function* () { - Services.search.currentEngine = originalEngine; - Services.search.removeEngine(engine); - Services.prefs.clearUserPref(SUGGEST_URLBAR_PREF, true); - Services.prefs.clearUserPref(ONEOFF_URLBAR_PREF); - }); -}); - -add_task(function* test_simpleQuery() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - - info("Simulate entering a simple search."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield searchInAwesomebar("simple query"); - EventUtils.sendKey("return"); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_URLBAR, "search_enter", 1); - Assert.equal(Object.keys(scalars[SCALAR_URLBAR]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "urlbar", "enter", {engine: "other-MozSearch"}]]); - - yield BrowserTestUtils.removeTab(tab); -}); - -add_task(function* test_searchAlias() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - - info("Search using a search alias."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield searchInAwesomebar("mozalias query"); - EventUtils.sendKey("return"); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_URLBAR, "search_alias", 1); - Assert.equal(Object.keys(scalars[SCALAR_URLBAR]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "urlbar", "alias", {engine: "other-MozSearch"}]]); - - yield BrowserTestUtils.removeTab(tab); -}); - -add_task(function* test_oneOff() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - - info("Perform a one-off search using the first engine."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield searchInAwesomebar("query"); - - info("Pressing Alt+Down to take us to the first one-off engine."); - EventUtils.synthesizeKey("VK_DOWN", { altKey: true }); - EventUtils.sendKey("return"); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_URLBAR, "search_oneoff", 1); - Assert.equal(Object.keys(scalars[SCALAR_URLBAR]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - checkKeyedHistogram(search_hist, 'other-MozSearch.urlbar', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "urlbar", "oneoff", {engine: "other-MozSearch"}]]); - - yield BrowserTestUtils.removeTab(tab); -}); - -add_task(function* test_suggestion() { - // Let's reset the counts. - Services.telemetry.clearScalars(); - Services.telemetry.clearEvents(); - let search_hist = getSearchCountsHistogram(); - - // Create an engine to generate search suggestions and add it as default - // for this test. - const url = getRootDirectory(gTestPath) + "usageTelemetrySearchSuggestions.xml"; - let suggestionEngine = yield new Promise((resolve, reject) => { - Services.search.addEngine(url, null, "", false, { - onSuccess(engine) { resolve(engine) }, - onError() { reject() } - }); - }); - - let previousEngine = Services.search.currentEngine; - Services.search.currentEngine = suggestionEngine; - - let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:blank"); - - info("Perform a one-off search using the first engine."); - let p = BrowserTestUtils.browserLoaded(tab.linkedBrowser); - yield searchInAwesomebar("query"); - info("Clicking the urlbar suggestion."); - clickURLBarSuggestion("queryfoo"); - yield p; - - // Check if the scalars contain the expected values. - const scalars = - Services.telemetry.snapshotKeyedScalars(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - checkKeyedScalar(scalars, SCALAR_URLBAR, "search_suggestion", 1); - Assert.equal(Object.keys(scalars[SCALAR_URLBAR]).length, 1, - "This search must only increment one entry in the scalar."); - - // Make sure SEARCH_COUNTS contains identical values. - let searchEngineId = 'other-' + suggestionEngine.name; - checkKeyedHistogram(search_hist, searchEngineId + '.urlbar', 1); - - // Also check events. - let events = Services.telemetry.snapshotBuiltinEvents(Ci.nsITelemetry.DATASET_RELEASE_CHANNEL_OPTIN, false); - events = events.filter(e => e[1] == "navigation" && e[2] == "search"); - checkEvents(events, [["navigation", "search", "urlbar", "suggestion", {engine: searchEngineId}]]); - - Services.search.currentEngine = previousEngine; - Services.search.removeEngine(suggestionEngine); - yield BrowserTestUtils.removeTab(tab); -}); diff --git a/browser/modules/test/browser_taskbar_preview.js b/browser/modules/test/browser_taskbar_preview.js deleted file mode 100644 index 89295b9e0..000000000 --- a/browser/modules/test/browser_taskbar_preview.js +++ /dev/null @@ -1,100 +0,0 @@ -function test() { - var isWin7OrHigher = false; - try { - let version = Cc["@mozilla.org/system-info;1"] - .getService(Ci.nsIPropertyBag2) - .getProperty("version"); - isWin7OrHigher = (parseFloat(version) >= 6.1); - } catch (ex) { } - - is(!!Win7Features, isWin7OrHigher, "Win7Features available when it should be"); - if (!isWin7OrHigher) - return; - - const ENABLE_PREF_NAME = "browser.taskbar.previews.enable"; - - let temp = {}; - Cu.import("resource:///modules/WindowsPreviewPerTab.jsm", temp); - let AeroPeek = temp.AeroPeek; - - waitForExplicitFinish(); - - gPrefService.setBoolPref(ENABLE_PREF_NAME, true); - - is(1, AeroPeek.windows.length, "Got the expected number of windows"); - - checkPreviews(1, "Browser starts with one preview"); - - gBrowser.addTab(); - gBrowser.addTab(); - gBrowser.addTab(); - - checkPreviews(4, "Correct number of previews after adding"); - - for (let preview of AeroPeek.previews) - ok(preview.visible, "Preview is shown as expected"); - - gPrefService.setBoolPref(ENABLE_PREF_NAME, false); - is(0, AeroPeek.previews.length, "Should have 0 previews when disabled"); - - gPrefService.setBoolPref(ENABLE_PREF_NAME, true); - checkPreviews(4, "Previews are back when re-enabling"); - for (let preview of AeroPeek.previews) - ok(preview.visible, "Preview is shown as expected after re-enabling"); - - [1, 2, 3, 4].forEach(function (idx) { - gBrowser.selectedTab = gBrowser.tabs[idx]; - ok(checkSelectedTab(), "Current tab is correctly selected"); - }); - - // Close #4 - getPreviewForTab(gBrowser.selectedTab).controller.onClose(); - checkPreviews(3, "Expected number of previews after closing selected tab via controller"); - ok(gBrowser.tabs.length == 3, "Successfully closed a tab"); - - // Select #1 - ok(getPreviewForTab(gBrowser.tabs[0]).controller.onActivate(), "Activation was accepted"); - ok(gBrowser.tabs[0].selected, "Correct tab was selected"); - checkSelectedTab(); - - // Remove #3 (non active) - gBrowser.removeTab(gBrowser.tabContainer.lastChild); - checkPreviews(2, "Expected number of previews after closing unselected via browser"); - - // Remove #1 (active) - gBrowser.removeTab(gBrowser.tabContainer.firstChild); - checkPreviews(1, "Expected number of previews after closing selected tab via browser"); - - // Add a new tab - gBrowser.addTab(); - checkPreviews(2); - // Check default selection - checkSelectedTab(); - - // Change selection - gBrowser.selectedTab = gBrowser.tabs[0]; - checkSelectedTab(); - // Close nonselected tab via controller - getPreviewForTab(gBrowser.tabs[1]).controller.onClose(); - checkPreviews(1); - - if (gPrefService.prefHasUserValue(ENABLE_PREF_NAME)) - gPrefService.setBoolPref(ENABLE_PREF_NAME, !gPrefService.getBoolPref(ENABLE_PREF_NAME)); - - finish(); - - function checkPreviews(aPreviews, msg) { - let nPreviews = AeroPeek.previews.length; - is(aPreviews, gBrowser.tabs.length, "Browser has expected number of tabs - " + msg); - is(nPreviews, gBrowser.tabs.length, "Browser has one preview per tab - " + msg); - is(nPreviews, aPreviews, msg || "Got expected number of previews"); - } - - function getPreviewForTab(tab) { - return window.gTaskbarTabGroup.previewFromTab(tab); - } - - function checkSelectedTab() { - return getPreviewForTab(gBrowser.selectedTab).active; - } -} diff --git a/browser/modules/test/browser_urlBar_zoom.js b/browser/modules/test/browser_urlBar_zoom.js deleted file mode 100644 index 9cb5c96c6..000000000 --- a/browser/modules/test/browser_urlBar_zoom.js +++ /dev/null @@ -1,73 +0,0 @@ -/* 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/. */ - -"use strict"; - -var initialPageZoom = ZoomManager.zoom; -const kTimeoutInMS = 20000; - -add_task(function* () { - info("Confirm whether the browser zoom is set to the default level"); - is(initialPageZoom, 1, "Page zoom is set to default (100%)"); - let zoomResetButton = document.getElementById("urlbar-zoom-button"); - is(zoomResetButton.hidden, true, "Zoom reset button is currently hidden"); - - info("Change zoom and confirm zoom button appears"); - let labelUpdatePromise = BrowserTestUtils.waitForAttribute("label", zoomResetButton); - FullZoom.enlarge(); - yield labelUpdatePromise; - info("Zoom increased to " + Math.floor(ZoomManager.zoom * 100) + "%"); - is(zoomResetButton.hidden, false, "Zoom reset button is now visible"); - let pageZoomLevel = Math.floor(ZoomManager.zoom * 100); - let expectedZoomLevel = 110; - let buttonZoomLevel = parseInt(zoomResetButton.getAttribute("label"), 10); - is(buttonZoomLevel, expectedZoomLevel, ("Button label updated successfully to " + Math.floor(ZoomManager.zoom * 100) + "%")); - - let zoomResetPromise = promiseObserverNotification("browser-fullZoom:zoomReset"); - zoomResetButton.click(); - yield zoomResetPromise; - pageZoomLevel = Math.floor(ZoomManager.zoom * 100); - expectedZoomLevel = 100; - is(pageZoomLevel, expectedZoomLevel, "Clicking zoom button successfully resets browser zoom to 100%"); - is(zoomResetButton.hidden, true, "Zoom reset button returns to being hidden"); - -}); - -add_task(function* () { - info("Confirm that URL bar zoom button doesn't appear when customizable zoom widget is added to toolbar"); - CustomizableUI.addWidgetToArea("zoom-controls", CustomizableUI.AREA_NAVBAR); - let zoomCustomizableWidget = document.getElementById("zoom-reset-button"); - let zoomResetButton = document.getElementById("urlbar-zoom-button"); - let zoomChangePromise = promiseObserverNotification("browser-fullZoom:zoomChange"); - FullZoom.enlarge(); - yield zoomChangePromise; - is(zoomResetButton.hidden, true, "URL zoom button remains hidden despite zoom increase"); - is(parseInt(zoomCustomizableWidget.label, 10), 110, "Customizable zoom widget's label has updated to " + zoomCustomizableWidget.label); -}); - -add_task(function* asyncCleanup() { - // reset zoom level and customizable widget - ZoomManager.zoom = initialPageZoom; - is(ZoomManager.zoom, 1, "Zoom level was restored"); - if (document.getElementById("zoom-controls")) { - CustomizableUI.removeWidgetFromArea("zoom-controls", CustomizableUI.AREA_NAVBAR); - ok(!document.getElementById("zoom-controls"), "Customizable zoom widget removed from toolbar"); - } - -}); - -function promiseObserverNotification(aObserver) { - let deferred = Promise.defer(); - function notificationCallback(e) { - Services.obs.removeObserver(notificationCallback, aObserver, false); - clearTimeout(timeoutId); - deferred.resolve(); - } - let timeoutId = setTimeout(() => { - Services.obs.removeObserver(notificationCallback, aObserver, false); - deferred.reject("Notification '" + aObserver + "' did not happen within 20 seconds."); - }, kTimeoutInMS); - Services.obs.addObserver(notificationCallback, aObserver, false); - return deferred.promise; -} diff --git a/browser/modules/test/contentSearch.js b/browser/modules/test/contentSearch.js deleted file mode 100644 index b5dddfe45..000000000 --- a/browser/modules/test/contentSearch.js +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 TEST_MSG = "ContentSearchTest"; -const SERVICE_EVENT_TYPE = "ContentSearchService"; -const CLIENT_EVENT_TYPE = "ContentSearchClient"; - -// Forward events from the in-content service to the test. -content.addEventListener(SERVICE_EVENT_TYPE, event => { - // The event dispatch code in content.js clones the event detail into the - // content scope. That's generally the right thing, but causes us to end - // up with an XrayWrapper to it here, which will screw us up when trying to - // serialize the object in sendAsyncMessage. Waive Xrays for the benefit of - // the test machinery. - sendAsyncMessage(TEST_MSG, Components.utils.waiveXrays(event.detail)); -}); - -// Forward messages from the test to the in-content service. -addMessageListener(TEST_MSG, msg => { - // If the message is a search, stop the page from loading and then tell the - // test that it loaded. - if (msg.data.type == "Search") { - waitForLoadAndStopIt(msg.data.expectedURL, url => { - sendAsyncMessage(TEST_MSG, { - type: "loadStopped", - url: url, - }); - }); - } - - content.dispatchEvent( - new content.CustomEvent(CLIENT_EVENT_TYPE, { - detail: msg.data, - }) - ); -}); - -function waitForLoadAndStopIt(expectedURL, callback) { - let Ci = Components.interfaces; - let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebProgress); - let listener = { - onStateChange: function (webProg, req, flags, status) { - if (req instanceof Ci.nsIChannel) { - let url = req.originalURI.spec; - dump("waitForLoadAndStopIt: onStateChange " + url + "\n"); - let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT | - Ci.nsIWebProgressListener.STATE_START; - if ((flags & docStart) && webProg.isTopLevel && url == expectedURL) { - webProgress.removeProgressListener(listener); - req.cancel(Components.results.NS_ERROR_FAILURE); - callback(url); - } - } - }, - QueryInterface: XPCOMUtils.generateQI([ - Ci.nsIWebProgressListener, - Ci.nsISupportsWeakReference, - ]), - }; - webProgress.addProgressListener(listener, Ci.nsIWebProgress.NOTIFY_ALL); - dump("waitForLoadAndStopIt: Waiting for URL to load: " + expectedURL + "\n"); -} diff --git a/browser/modules/test/contentSearchBadImage.xml b/browser/modules/test/contentSearchBadImage.xml deleted file mode 100644 index 6e4cb60a5..000000000 --- a/browser/modules/test/contentSearchBadImage.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> -<ShortName>browser_ContentSearch contentSearchBadImage.xml</ShortName> -<Url type="text/html" method="GET" template="http://browser-ContentSearch.com/contentSearchBadImage" rel="searchform"/> -<Image width="16" height="16">data:image/x-icon;base64,notbase64</Image> -</SearchPlugin> diff --git a/browser/modules/test/contentSearchSuggestions.sjs b/browser/modules/test/contentSearchSuggestions.sjs deleted file mode 100644 index 1978b4f66..000000000 --- a/browser/modules/test/contentSearchSuggestions.sjs +++ /dev/null @@ -1,9 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -function handleRequest(req, resp) { - let suffixes = ["foo", "bar"]; - let data = [req.queryString, suffixes.map(s => req.queryString + s)]; - resp.setHeader("Content-Type", "application/json", false); - resp.write(JSON.stringify(data)); -} diff --git a/browser/modules/test/contentSearchSuggestions.xml b/browser/modules/test/contentSearchSuggestions.xml deleted file mode 100644 index 81c23379c..000000000 --- a/browser/modules/test/contentSearchSuggestions.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> -<ShortName>browser_ContentSearch contentSearchSuggestions.xml</ShortName> -<Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/modules/test/contentSearchSuggestions.sjs?{searchTerms}"/> -<Url type="text/html" method="GET" template="http://browser-ContentSearch.com/contentSearchSuggestions" rel="searchform"/> -</SearchPlugin> diff --git a/browser/modules/test/head.js b/browser/modules/test/head.js deleted file mode 100644 index be0215156..000000000 --- a/browser/modules/test/head.js +++ /dev/null @@ -1,113 +0,0 @@ -Cu.import("resource://gre/modules/Promise.jsm"); - -const SINGLE_TRY_TIMEOUT = 100; -const NUMBER_OF_TRIES = 30; - -function waitForConditionPromise(condition, timeoutMsg, tryCount=NUMBER_OF_TRIES) { - let defer = Promise.defer(); - let tries = 0; - function checkCondition() { - if (tries >= tryCount) { - defer.reject(timeoutMsg); - } - var conditionPassed; - try { - conditionPassed = condition(); - } catch (e) { - return defer.reject(e); - } - if (conditionPassed) { - return defer.resolve(); - } - tries++; - setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); - return undefined; - } - setTimeout(checkCondition, SINGLE_TRY_TIMEOUT); - return defer.promise; -} - -function waitForCondition(condition, nextTest, errorMsg) { - waitForConditionPromise(condition, errorMsg).then(nextTest, (reason) => { - ok(false, reason + (reason.stack ? "\n" + reason.stack : "")); - }); -} - -/** - * Checks if the snapshotted keyed scalars contain the expected - * data. - * - * @param {Object} scalars - * The snapshot of the keyed scalars. - * @param {String} scalarName - * The name of the keyed scalar to check. - * @param {String} key - * The key that must be within the keyed scalar. - * @param {String|Boolean|Number} expectedValue - * The expected value for the provided key in the scalar. - */ -function checkKeyedScalar(scalars, scalarName, key, expectedValue) { - Assert.ok(scalarName in scalars, - scalarName + " must be recorded."); - Assert.ok(key in scalars[scalarName], - scalarName + " must contain the '" + key + "' key."); - Assert.ok(scalars[scalarName][key], expectedValue, - scalarName + "['" + key + "'] must contain the expected value"); -} - -/** - * An utility function to write some text in the search input box - * in a content page. - * @param {Object} browser - * The browser that contains the content. - * @param {String} text - * The string to write in the search field. - * @param {String} fieldName - * The name of the field to write to. - */ -let typeInSearchField = Task.async(function* (browser, text, fieldName) { - yield ContentTask.spawn(browser, { fieldName, text }, function* ({fieldName, text}) { - // Avoid intermittent failures. - if (fieldName === "searchText") { - content.wrappedJSObject.gContentSearchController.remoteTimeout = 5000; - } - // Put the focus on the search box. - let searchInput = content.document.getElementById(fieldName); - searchInput.focus(); - searchInput.value = text; - }); -}); - -/** - * Clear and get the SEARCH_COUNTS histogram. - */ -function getSearchCountsHistogram() { - let search_hist = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS"); - search_hist.clear(); - return search_hist; -} - -/** - * Check that the keyed histogram contains the right value. - */ -function checkKeyedHistogram(h, key, expectedValue) { - const snapshot = h.snapshot(); - Assert.ok(key in snapshot, `The histogram must contain ${key}.`); - Assert.equal(snapshot[key].sum, expectedValue, `The key ${key} must contain ${expectedValue}.`); -} - -function checkEvents(events, expectedEvents) { - if (!Services.telemetry.canRecordExtended) { - // Currently we only collect the tested events when extended Telemetry is enabled. - return; - } - - Assert.equal(events.length, expectedEvents.length, "Should have matching amount of events."); - - // Strip timestamps from the events for easier comparison. - events = events.map(e => e.slice(1)); - - for (let i = 0; i < events.length; ++i) { - Assert.deepEqual(events[i], expectedEvents[i], "Events should match."); - } -} diff --git a/browser/modules/test/unit/social/.eslintrc.js b/browser/modules/test/unit/social/.eslintrc.js deleted file mode 100644 index d35787cd2..000000000 --- a/browser/modules/test/unit/social/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../../testing/xpcshell/xpcshell.eslintrc.js" - ] -}; diff --git a/browser/modules/test/unit/social/blocklist.xml b/browser/modules/test/unit/social/blocklist.xml deleted file mode 100644 index c8d72d624..000000000 --- a/browser/modules/test/unit/social/blocklist.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0"?> -<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist"> - <emItems> - <emItem blockID="s1" id="bad.com@services.mozilla.org"></emItem> - </emItems> -</blocklist> diff --git a/browser/modules/test/unit/social/head.js b/browser/modules/test/unit/social/head.js deleted file mode 100644 index 0beabb685..000000000 --- a/browser/modules/test/unit/social/head.js +++ /dev/null @@ -1,210 +0,0 @@ -/* 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/. */ - -var { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -var Social, SocialService; - -var manifests = [ - { - name: "provider 1", - origin: "https://example1.com", - sidebarURL: "https://example1.com/sidebar/", - }, - { - name: "provider 2", - origin: "https://example2.com", - sidebarURL: "https://example1.com/sidebar/", - } -]; - -const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest."); - -// SocialProvider class relies on blocklisting being enabled. To enable -// blocklisting, we have to setup an app and initialize the blocklist (see -// initApp below). -const gProfD = do_get_profile(); - -function createAppInfo(ID, name, version, platformVersion="1.0") { - let tmp = {}; - Cu.import("resource://testing-common/AppInfo.jsm", tmp); - tmp.updateAppInfo({ - ID, name, version, platformVersion, - crashReporter: true, - }); - gAppInfo = tmp.getAppInfo(); -} - -function initApp() { - createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9"); - // prepare a blocklist file for the blocklist service - var blocklistFile = gProfD.clone(); - blocklistFile.append("blocklist.xml"); - if (blocklistFile.exists()) - blocklistFile.remove(false); - var source = do_get_file("blocklist.xml"); - source.copyTo(gProfD, "blocklist.xml"); - blocklistFile.lastModifiedTime = Date.now(); - - - let internalManager = Cc["@mozilla.org/addons/integration;1"]. - getService(Ci.nsIObserver). - QueryInterface(Ci.nsITimerCallback); - - internalManager.observe(null, "addons-startup", null); -} - -function setManifestPref(manifest) { - let string = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - string.data = JSON.stringify(manifest); - Services.prefs.setComplexValue("social.manifest." + manifest.origin, Ci.nsISupportsString, string); -} - -function do_wait_observer(obsTopic, cb) { - function observer(subject, topic, data) { - Services.obs.removeObserver(observer, topic); - cb(); - } - Services.obs.addObserver(observer, obsTopic, false); -} - -function do_add_providers(cb) { - // run only after social is already initialized - SocialService.addProvider(manifests[0], function() { - do_wait_observer("social:providers-changed", function() { - do_check_eq(Social.providers.length, 2, "2 providers installed"); - do_execute_soon(cb); - }); - SocialService.addProvider(manifests[1]); - }); -} - -function do_initialize_social(enabledOnStartup, cb) { - initApp(); - - if (enabledOnStartup) { - // set prefs before initializing social - manifests.forEach(function (manifest) { - setManifestPref(manifest); - }); - // Set both providers active and flag the first one as "current" - let activeVal = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - let active = {}; - for (let m of manifests) - active[m.origin] = 1; - activeVal.data = JSON.stringify(active); - Services.prefs.setComplexValue("social.activeProviders", - Ci.nsISupportsString, activeVal); - - do_register_cleanup(function() { - manifests.forEach(function (manifest) { - Services.prefs.clearUserPref("social.manifest." + manifest.origin); - }); - Services.prefs.clearUserPref("social.activeProviders"); - }); - - // expecting 2 providers installed - do_wait_observer("social:providers-changed", function() { - do_check_eq(Social.providers.length, 2, "2 providers installed"); - do_execute_soon(cb); - }); - } - - // import and initialize everything - SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService; - do_check_eq(enabledOnStartup, SocialService.hasEnabledProviders, "Service has enabled providers"); - Social = Cu.import("resource:///modules/Social.jsm", {}).Social; - do_check_false(Social.initialized, "Social is not initialized"); - Social.init(); - do_check_true(Social.initialized, "Social is initialized"); - if (!enabledOnStartup) - do_execute_soon(cb); -} - -function AsyncRunner() { - do_test_pending(); - do_register_cleanup(() => this.destroy()); - - this._callbacks = { - done: do_test_finished, - error: function (err) { - // xpcshell test functions like do_check_eq throw NS_ERROR_ABORT on - // failure. Ignore those so they aren't rethrown here. - if (err !== Cr.NS_ERROR_ABORT) { - if (err.stack) { - err = err + " - See following stack:\n" + err.stack + - "\nUseless do_throw stack"; - } - do_throw(err); - } - }, - consoleError: function (scriptErr) { - // Try to ensure the error is related to the test. - let filename = scriptErr.sourceName || scriptErr.toString() || ""; - if (filename.indexOf("/toolkit/components/social/") >= 0) - do_throw(scriptErr); - }, - }; - this._iteratorQueue = []; - - // This catches errors reported to the console, e.g., via Cu.reportError, but - // not on the runner's stack. - Cc["@mozilla.org/consoleservice;1"]. - getService(Ci.nsIConsoleService). - registerListener(this); -} - -AsyncRunner.prototype = { - - appendIterator: function appendIterator(iter) { - this._iteratorQueue.push(iter); - }, - - next: function next(arg) { - if (!this._iteratorQueue.length) { - this.destroy(); - this._callbacks.done(); - return; - } - - try { - var { done, value: val } = this._iteratorQueue[0].next(arg); - if (done) { - this._iteratorQueue.shift(); - this.next(); - return; - } - } - catch (err) { - this._callbacks.error(err); - } - - // val is an iterator => prepend it to the queue and start on it - // val is otherwise truthy => call next - if (val) { - if (typeof(val) != "boolean") - this._iteratorQueue.unshift(val); - this.next(); - } - }, - - destroy: function destroy() { - Cc["@mozilla.org/consoleservice;1"]. - getService(Ci.nsIConsoleService). - unregisterListener(this); - this.destroy = function alreadyDestroyed() {}; - }, - - observe: function observe(msg) { - if (msg instanceof Ci.nsIScriptError && - !(msg.flags & Ci.nsIScriptError.warningFlag)) - { - this._callbacks.consoleError(msg); - } - }, -}; diff --git a/browser/modules/test/unit/social/test_SocialService.js b/browser/modules/test/unit/social/test_SocialService.js deleted file mode 100644 index e6f354fed..000000000 --- a/browser/modules/test/unit/social/test_SocialService.js +++ /dev/null @@ -1,166 +0,0 @@ -/* 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/. */ - -Cu.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils", - "resource://testing-common/PlacesTestUtils.jsm"); - -function run_test() { - initApp(); - - // NOTE: none of the manifests here can have a workerURL set, or we attempt - // to create a FrameWorker and that fails under xpcshell... - let manifests = [ - { // normal provider - name: "provider 1", - origin: "https://example1.com", - shareURL: "https://example1.com/share/", - }, - { // provider without workerURL - name: "provider 2", - origin: "https://example2.com", - shareURL: "https://example2.com/share/", - } - ]; - - Cu.import("resource:///modules/SocialService.jsm"); - - let runner = new AsyncRunner(); - let next = runner.next.bind(runner); - runner.appendIterator(testAddProviders(manifests, next)); - runner.appendIterator(testGetProvider(manifests, next)); - runner.appendIterator(testGetProviderList(manifests, next)); - runner.appendIterator(testAddRemoveProvider(manifests, next)); - runner.appendIterator(testIsSameOrigin(manifests, next)); - runner.appendIterator(testResolveUri (manifests, next)); - runner.appendIterator(testOrderedProviders(manifests, next)); - runner.appendIterator(testRemoveProviders(manifests, next)); - runner.next(); -} - -function* testAddProviders(manifests, next) { - do_check_false(SocialService.enabled); - let provider = yield SocialService.addProvider(manifests[0], next); - do_check_true(SocialService.enabled); - do_check_false(provider.enabled); - provider = yield SocialService.addProvider(manifests[1], next); - do_check_false(provider.enabled); -} - -function* testRemoveProviders(manifests, next) { - do_check_true(SocialService.enabled); - yield SocialService.disableProvider(manifests[0].origin, next); - yield SocialService.disableProvider(manifests[1].origin, next); - do_check_false(SocialService.enabled); -} - -function* testGetProvider(manifests, next) { - for (let i = 0; i < manifests.length; i++) { - let manifest = manifests[i]; - let provider = yield SocialService.getProvider(manifest.origin, next); - do_check_neq(provider, null); - do_check_eq(provider.name, manifest.name); - do_check_eq(provider.workerURL, manifest.workerURL); - do_check_eq(provider.origin, manifest.origin); - } - do_check_eq((yield SocialService.getProvider("bogus", next)), null); -} - -function* testGetProviderList(manifests, next) { - let providers = yield SocialService.getProviderList(next); - do_check_true(providers.length >= manifests.length); - for (let i = 0; i < manifests.length; i++) { - let providerIdx = providers.map(p => p.origin).indexOf(manifests[i].origin); - let provider = providers[providerIdx]; - do_check_true(!!provider); - do_check_false(provider.enabled); - do_check_eq(provider.workerURL, manifests[i].workerURL); - do_check_eq(provider.name, manifests[i].name); - } -} - -function* testAddRemoveProvider(manifests, next) { - var threw; - try { - // Adding a provider whose origin already exists should fail - SocialService.addProvider(manifests[0]); - } catch (ex) { - threw = ex; - } - do_check_neq(threw.toString().indexOf("SocialService.addProvider: provider with this origin already exists"), -1); - - let originalProviders = yield SocialService.getProviderList(next); - - // Check that provider installation succeeds - let newProvider = yield SocialService.addProvider({ - name: "foo", - origin: "http://example3.com" - }, next); - let retrievedNewProvider = yield SocialService.getProvider(newProvider.origin, next); - do_check_eq(newProvider, retrievedNewProvider); - - let providersAfter = yield SocialService.getProviderList(next); - do_check_eq(providersAfter.length, originalProviders.length + 1); - do_check_neq(providersAfter.indexOf(newProvider), -1); - - // Now remove the provider - yield SocialService.disableProvider(newProvider.origin, next); - providersAfter = yield SocialService.getProviderList(next); - do_check_eq(providersAfter.length, originalProviders.length); - do_check_eq(providersAfter.indexOf(newProvider), -1); - newProvider = yield SocialService.getProvider(newProvider.origin, next); - do_check_true(!newProvider); -} - -function* testIsSameOrigin(manifests, next) { - let providers = yield SocialService.getProviderList(next); - let provider = providers[0]; - // provider.origin is a string. - do_check_true(provider.isSameOrigin(provider.origin)); - do_check_true(provider.isSameOrigin(Services.io.newURI(provider.origin, null, null))); - do_check_true(provider.isSameOrigin(provider.origin + "/some-sub-page")); - do_check_true(provider.isSameOrigin(Services.io.newURI(provider.origin + "/some-sub-page", null, null))); - do_check_false(provider.isSameOrigin("http://something.com")); - do_check_false(provider.isSameOrigin(Services.io.newURI("http://something.com", null, null))); - do_check_false(provider.isSameOrigin("data:text/html,<p>hi")); - do_check_true(provider.isSameOrigin("data:text/html,<p>hi", true)); - do_check_false(provider.isSameOrigin(Services.io.newURI("data:text/html,<p>hi", null, null))); - do_check_true(provider.isSameOrigin(Services.io.newURI("data:text/html,<p>hi", null, null), true)); - // we explicitly handle null and return false - do_check_false(provider.isSameOrigin(null)); -} - -function* testResolveUri(manifests, next) { - let providers = yield SocialService.getProviderList(next); - let provider = providers[0]; - do_check_eq(provider.resolveUri(provider.origin).spec, provider.origin + "/"); - do_check_eq(provider.resolveUri("foo.html").spec, provider.origin + "/foo.html"); - do_check_eq(provider.resolveUri("/foo.html").spec, provider.origin + "/foo.html"); - do_check_eq(provider.resolveUri("http://somewhereelse.com/foo.html").spec, "http://somewhereelse.com/foo.html"); - do_check_eq(provider.resolveUri("data:text/html,<p>hi").spec, "data:text/html,<p>hi"); -} - -function* testOrderedProviders(manifests, next) { - let providers = yield SocialService.getProviderList(next); - - // add visits for only one of the providers - let visits = []; - let startDate = Date.now() * 1000; - for (let i = 0; i < 10; i++) { - visits.push({ - uri: Services.io.newURI(providers[1].shareURL + i, null, null), - visitDate: startDate + i - }); - } - - PlacesTestUtils.addVisits(visits).then(next); - yield; - let orderedProviders = yield SocialService.getOrderedProviderList(next); - do_check_eq(orderedProviders[0], providers[1]); - do_check_eq(orderedProviders[1], providers[0]); - do_check_true(orderedProviders[0].frecency > orderedProviders[1].frecency); - PlacesTestUtils.clearHistory().then(next); - yield; -} diff --git a/browser/modules/test/unit/social/test_SocialServiceMigration21.js b/browser/modules/test/unit/social/test_SocialServiceMigration21.js deleted file mode 100644 index dfe6183bf..000000000 --- a/browser/modules/test/unit/social/test_SocialServiceMigration21.js +++ /dev/null @@ -1,54 +0,0 @@ -/* 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/. */ - -Cu.import("resource://gre/modules/Services.jsm"); - -const DEFAULT_PREFS = Services.prefs.getDefaultBranch("social.manifest."); - -function run_test() { - // Test must run at startup for migration to occur, so we can only test - // one migration per test file - initApp(); - - // NOTE: none of the manifests here can have a workerURL set, or we attempt - // to create a FrameWorker and that fails under xpcshell... - let manifest = { // normal provider - name: "provider 1", - origin: "https://example1.com", - builtin: true // as of fx22 this should be true for default prefs - }; - - DEFAULT_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest)); - Services.prefs.setBoolPref("social.active", true); - - Cu.import("resource:///modules/SocialService.jsm"); - - let runner = new AsyncRunner(); - let next = runner.next.bind(runner); - runner.appendIterator(testMigration(manifest, next)); - runner.next(); -} - -function* testMigration(manifest, next) { - // look at social.activeProviders, we should have migrated into that, and - // we should be set as a user level pref after migration - do_check_false(MANIFEST_PREFS.prefHasUserValue(manifest.origin)); - // we need to access the providers for everything to initialize - yield SocialService.getProviderList(next); - do_check_true(SocialService.enabled); - do_check_true(Services.prefs.prefHasUserValue("social.activeProviders")); - - let activeProviders; - let pref = Services.prefs.getComplexValue("social.activeProviders", - Ci.nsISupportsString); - activeProviders = JSON.parse(pref); - do_check_true(activeProviders[manifest.origin]); - do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin)); - do_check_true(JSON.parse(DEFAULT_PREFS.getCharPref(manifest.origin)).builtin); - - let userPref = JSON.parse(MANIFEST_PREFS.getCharPref(manifest.origin)); - do_check_true(parseInt(userPref.updateDate) > 0); - // migrated providers wont have an installDate - do_check_true(userPref.installDate === 0); -} diff --git a/browser/modules/test/unit/social/test_SocialServiceMigration22.js b/browser/modules/test/unit/social/test_SocialServiceMigration22.js deleted file mode 100644 index 1a3953175..000000000 --- a/browser/modules/test/unit/social/test_SocialServiceMigration22.js +++ /dev/null @@ -1,67 +0,0 @@ -/* 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/. */ - -Cu.import("resource://gre/modules/Services.jsm"); - -const DEFAULT_PREFS = Services.prefs.getDefaultBranch("social.manifest."); - -function run_test() { - // Test must run at startup for migration to occur, so we can only test - // one migration per test file - initApp(); - - // NOTE: none of the manifests here can have a workerURL set, or we attempt - // to create a FrameWorker and that fails under xpcshell... - let manifest = { // normal provider - name: "provider 1", - origin: "https://example1.com", - builtin: true // as of fx22 this should be true for default prefs - }; - - DEFAULT_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest)); - - // Set both providers active and flag the first one as "current" - let activeVal = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - let active = {}; - active[manifest.origin] = 1; - // bad.origin tests that a missing manifest does not break migration, bug 859715 - active["bad.origin"] = 1; - activeVal.data = JSON.stringify(active); - Services.prefs.setComplexValue("social.activeProviders", - Ci.nsISupportsString, activeVal); - - Cu.import("resource:///modules/SocialService.jsm"); - - let runner = new AsyncRunner(); - let next = runner.next.bind(runner); - runner.appendIterator(testMigration(manifest, next)); - runner.next(); -} - -function* testMigration(manifest, next) { - // look at social.activeProviders, we should have migrated into that, and - // we should be set as a user level pref after migration - do_check_false(MANIFEST_PREFS.prefHasUserValue(manifest.origin)); - // we need to access the providers for everything to initialize - yield SocialService.getProviderList(next); - do_check_true(SocialService.enabled); - do_check_true(Services.prefs.prefHasUserValue("social.activeProviders")); - - let activeProviders; - let pref = Services.prefs.getComplexValue("social.activeProviders", - Ci.nsISupportsString); - activeProviders = JSON.parse(pref); - do_check_true(activeProviders[manifest.origin]); - do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin)); - do_check_true(JSON.parse(DEFAULT_PREFS.getCharPref(manifest.origin)).builtin); - - let userPref = JSON.parse(MANIFEST_PREFS.getCharPref(manifest.origin)); - do_check_true(parseInt(userPref.updateDate) > 0); - // migrated providers wont have an installDate - do_check_true(userPref.installDate === 0); - - // bug 859715, this should have been removed during migration - do_check_false(!!activeProviders["bad.origin"]); -} diff --git a/browser/modules/test/unit/social/test_SocialServiceMigration29.js b/browser/modules/test/unit/social/test_SocialServiceMigration29.js deleted file mode 100644 index 824673ddf..000000000 --- a/browser/modules/test/unit/social/test_SocialServiceMigration29.js +++ /dev/null @@ -1,61 +0,0 @@ -/* 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/. */ - -Cu.import("resource://gre/modules/Services.jsm"); - - -function run_test() { - // Test must run at startup for migration to occur, so we can only test - // one migration per test file - initApp(); - - // NOTE: none of the manifests here can have a workerURL set, or we attempt - // to create a FrameWorker and that fails under xpcshell... - let manifest = { // normal provider - name: "provider 1", - origin: "https://example1.com", - }; - - MANIFEST_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest)); - - // Set both providers active and flag the first one as "current" - let activeVal = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - let active = {}; - active[manifest.origin] = 1; - activeVal.data = JSON.stringify(active); - Services.prefs.setComplexValue("social.activeProviders", - Ci.nsISupportsString, activeVal); - - // social.enabled pref is the key focus of this test. We set the user pref, - // and then migration should a) remove the provider from activeProviders and - // b) unset social.enabled - Services.prefs.setBoolPref("social.enabled", false); - - Cu.import("resource:///modules/SocialService.jsm"); - - let runner = new AsyncRunner(); - let next = runner.next.bind(runner); - runner.appendIterator(testMigration(manifest, next)); - runner.next(); -} - -function* testMigration(manifest, next) { - // look at social.activeProviders, we should have migrated into that, and - // we should be set as a user level pref after migration - do_check_true(Services.prefs.prefHasUserValue("social.enabled")); - do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin)); - // we need to access the providers for everything to initialize - yield SocialService.getProviderList(next); - do_check_false(SocialService.enabled); - do_check_false(Services.prefs.prefHasUserValue("social.enabled")); - do_check_true(Services.prefs.prefHasUserValue("social.activeProviders")); - - let activeProviders; - let pref = Services.prefs.getComplexValue("social.activeProviders", - Ci.nsISupportsString).data; - activeProviders = JSON.parse(pref); - do_check_true(activeProviders[manifest.origin] == undefined); - do_check_true(MANIFEST_PREFS.prefHasUserValue(manifest.origin)); -} diff --git a/browser/modules/test/unit/social/test_social.js b/browser/modules/test/unit/social/test_social.js deleted file mode 100644 index 3117306c1..000000000 --- a/browser/modules/test/unit/social/test_social.js +++ /dev/null @@ -1,32 +0,0 @@ -/* 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/. */ - -function run_test() { - // we are testing worker startup specifically - do_test_pending(); - add_test(testStartupEnabled); - add_test(testDisableAfterStartup); - do_initialize_social(true, run_next_test); -} - -function testStartupEnabled() { - // wait on startup before continuing - do_check_eq(Social.providers.length, 2, "two social providers enabled"); - do_check_true(Social.providers[0].enabled, "provider 0 is enabled"); - do_check_true(Social.providers[1].enabled, "provider 1 is enabled"); - run_next_test(); -} - -function testDisableAfterStartup() { - let SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService; - SocialService.disableProvider(Social.providers[0].origin, function() { - do_wait_observer("social:providers-changed", function() { - do_check_eq(Social.enabled, false, "Social is disabled"); - do_check_eq(Social.providers.length, 0, "no social providers available"); - do_test_finished(); - run_next_test(); - }); - SocialService.disableProvider(Social.providers[0].origin) - }); -} diff --git a/browser/modules/test/unit/social/test_socialDisabledStartup.js b/browser/modules/test/unit/social/test_socialDisabledStartup.js deleted file mode 100644 index a2f7a1d5a..000000000 --- a/browser/modules/test/unit/social/test_socialDisabledStartup.js +++ /dev/null @@ -1,29 +0,0 @@ -/* 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/. */ - -function run_test() { - // we are testing worker startup specifically - do_test_pending(); - add_test(testStartupDisabled); - add_test(testEnableAfterStartup); - do_initialize_social(false, run_next_test); -} - -function testStartupDisabled() { - // wait on startup before continuing - do_check_false(Social.enabled, "Social is disabled"); - do_check_eq(Social.providers.length, 0, "zero social providers available"); - run_next_test(); -} - -function testEnableAfterStartup() { - do_add_providers(function () { - do_check_true(Social.enabled, "Social is enabled"); - do_check_eq(Social.providers.length, 2, "two social providers available"); - do_check_true(Social.providers[0].enabled, "provider 0 is enabled"); - do_check_true(Social.providers[1].enabled, "provider 1 is enabled"); - do_test_finished(); - run_next_test(); - }); -} diff --git a/browser/modules/test/unit/social/xpcshell.ini b/browser/modules/test/unit/social/xpcshell.ini deleted file mode 100644 index 277dd4f49..000000000 --- a/browser/modules/test/unit/social/xpcshell.ini +++ /dev/null @@ -1,13 +0,0 @@ -[DEFAULT] -head = head.js -tail = -firefox-appdir = browser -skip-if = toolkit == 'android' -support-files = blocklist.xml - -[test_social.js] -[test_socialDisabledStartup.js] -[test_SocialService.js] -[test_SocialServiceMigration21.js] -[test_SocialServiceMigration22.js] -[test_SocialServiceMigration29.js] diff --git a/browser/modules/test/usageTelemetrySearchSuggestions.sjs b/browser/modules/test/usageTelemetrySearchSuggestions.sjs deleted file mode 100644 index 1978b4f66..000000000 --- a/browser/modules/test/usageTelemetrySearchSuggestions.sjs +++ /dev/null @@ -1,9 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -function handleRequest(req, resp) { - let suffixes = ["foo", "bar"]; - let data = [req.queryString, suffixes.map(s => req.queryString + s)]; - resp.setHeader("Content-Type", "application/json", false); - resp.write(JSON.stringify(data)); -} diff --git a/browser/modules/test/usageTelemetrySearchSuggestions.xml b/browser/modules/test/usageTelemetrySearchSuggestions.xml deleted file mode 100644 index 76276045d..000000000 --- a/browser/modules/test/usageTelemetrySearchSuggestions.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> -<ShortName>browser_UsageTelemetry usageTelemetrySearchSuggestions.xml</ShortName> -<Url type="application/x-suggestions+json" method="GET" template="http://mochi.test:8888/browser/browser/modules/test/usageTelemetrySearchSuggestions.sjs?{searchTerms}"/> -<Url type="text/html" method="GET" template="http://example.com" rel="searchform"/> -</SearchPlugin> diff --git a/browser/modules/test/xpcshell/.eslintrc.js b/browser/modules/test/xpcshell/.eslintrc.js deleted file mode 100644 index fee088c17..000000000 --- a/browser/modules/test/xpcshell/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../testing/xpcshell/xpcshell.eslintrc.js" - ] -}; diff --git a/browser/modules/test/xpcshell/test_AttributionCode.js b/browser/modules/test/xpcshell/test_AttributionCode.js deleted file mode 100644 index d979ae845..000000000 --- a/browser/modules/test/xpcshell/test_AttributionCode.js +++ /dev/null @@ -1,110 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ -"use strict"; - -const {interfaces: Ci, utils: Cu} = Components; - -Cu.import("resource://gre/modules/AppConstants.jsm"); -Cu.import("resource:///modules/AttributionCode.jsm"); -Cu.import('resource://gre/modules/osfile.jsm'); -Cu.import("resource://gre/modules/Services.jsm"); - -let validAttrCodes = [ - {code: "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)%26content%3D(not%20set)", - parsed: {"source": "google.com", "medium": "organic", - "campaign": "(not%20set)", "content": "(not%20set)"}}, - {code: "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D%26content%3D", - parsed: {"source": "google.com", "medium": "organic"}}, - {code: "source%3Dgoogle.com%26medium%3Dorganic%26campaign%3D(not%20set)", - parsed: {"source": "google.com", "medium": "organic", "campaign": "(not%20set)"}}, - {code: "source%3Dgoogle.com%26medium%3Dorganic", - parsed: {"source": "google.com", "medium": "organic"}}, - {code: "source%3Dgoogle.com", - parsed: {"source": "google.com"}}, - {code: "medium%3Dgoogle.com", - parsed: {"medium": "google.com"}}, - {code: "campaign%3Dgoogle.com", - parsed: {"campaign": "google.com"}}, - {code: "content%3Dgoogle.com", - parsed: {"content": "google.com"}} -]; - -let invalidAttrCodes = [ - // Empty string - "", - // Not escaped - "source=google.com&medium=organic&campaign=(not set)&content=(not set)", - // Too long - "source%3Dreallyreallyreallyreallyreallyreallyreallyreallyreallylongdomain.com%26medium%3Dorganic%26campaign%3D(not%20set)%26content%3Dalmostexactlyenoughcontenttomakethisstringlongerthanthe200characterlimit", - // Unknown key name - "source%3Dgoogle.com%26medium%3Dorganic%26large%3Dgeneticallymodified", - // Empty key name - "source%3Dgoogle.com%26medium%3Dorganic%26%3Dgeneticallymodified" -]; - -function* writeAttributionFile(data) { - let appDir = Services.dirsvc.get("LocalAppData", Ci.nsIFile); - let file = appDir.clone(); - file.append(Services.appinfo.vendor || "mozilla"); - file.append(AppConstants.MOZ_APP_NAME); - - yield OS.File.makeDir(file.path, - {from: appDir.path, ignoreExisting: true}); - - file.append("postSigningData"); - yield OS.File.writeAtomic(file.path, data); -} - -/** - * Test validation of attribution codes, - * to make sure we reject bad ones and accept good ones. - */ -add_task(function* testValidAttrCodes() { - for (let entry of validAttrCodes) { - AttributionCode._clearCache(); - yield writeAttributionFile(entry.code); - let result = yield AttributionCode.getAttrDataAsync(); - Assert.deepEqual(result, entry.parsed, - "Parsed code should match expected value, code was: " + entry.code); - } - AttributionCode._clearCache(); -}); - -/** - * Make sure codes with various formatting errors are not seen as valid. - */ -add_task(function* testInvalidAttrCodes() { - for (let code of invalidAttrCodes) { - AttributionCode._clearCache(); - yield writeAttributionFile(code); - let result = yield AttributionCode.getAttrDataAsync(); - Assert.deepEqual(result, {}, - "Code should have failed to parse: " + code); - } - AttributionCode._clearCache(); -}); - -/** - * Test the cache by deleting the attribution data file - * and making sure we still get the expected code. - */ -add_task(function* testDeletedFile() { - // Set up the test by clearing the cache and writing a valid file. - yield writeAttributionFile(validAttrCodes[0].code); - let result = yield AttributionCode.getAttrDataAsync(); - Assert.deepEqual(result, validAttrCodes[0].parsed, - "The code should be readable directly from the file"); - - // Delete the file and make sure we can still read the value back from cache. - yield AttributionCode.deleteFileAsync(); - result = yield AttributionCode.getAttrDataAsync(); - Assert.deepEqual(result, validAttrCodes[0].parsed, - "The code should be readable from the cache"); - - // Clear the cache and check we can't read anything. - AttributionCode._clearCache(); - result = yield AttributionCode.getAttrDataAsync(); - Assert.deepEqual(result, {}, - "Shouldn't be able to get a code after file is deleted and cache is cleared"); -}); diff --git a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js b/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js deleted file mode 100644 index 712f52fa6..000000000 --- a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js +++ /dev/null @@ -1,1854 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ -"use strict"; - -/** - * This file tests the DirectoryLinksProvider singleton in the DirectoryLinksProvider.jsm module. - */ - -var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu, Constructor: CC } = Components; -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource:///modules/DirectoryLinksProvider.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/Http.jsm"); -Cu.import("resource://testing-common/httpd.js"); -Cu.import("resource://gre/modules/osfile.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/PlacesUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils", - "resource://gre/modules/NewTabUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesTestUtils", - "resource://testing-common/PlacesTestUtils.jsm"); - -do_get_profile(); - -const DIRECTORY_LINKS_FILE = "directoryLinks.json"; -const DIRECTORY_FRECENCY = 1000; -const SUGGESTED_FRECENCY = Infinity; -const kURLData = {"directory": [{"url":"http://example.com", "title":"LocalSource"}]}; -const kTestURL = 'data:application/json,' + JSON.stringify(kURLData); - -// DirectoryLinksProvider preferences -const kLocalePref = DirectoryLinksProvider._observedPrefs.prefSelectedLocale; -const kSourceUrlPref = DirectoryLinksProvider._observedPrefs.linksURL; -const kPingUrlPref = "browser.newtabpage.directory.ping"; -const kNewtabEnhancedPref = "browser.newtabpage.enhanced"; - -// httpd settings -var server; -const kDefaultServerPort = 9000; -const kBaseUrl = "http://localhost:" + kDefaultServerPort; -const kExamplePath = "/exampleTest/"; -const kFailPath = "/fail/"; -const kPingPath = "/ping/"; -const kExampleURL = kBaseUrl + kExamplePath; -const kFailURL = kBaseUrl + kFailPath; -const kPingUrl = kBaseUrl + kPingPath; - -// app/profile/firefox.js are not avaialble in xpcshell: hence, preset them -Services.prefs.setCharPref(kLocalePref, "en-US"); -Services.prefs.setCharPref(kSourceUrlPref, kTestURL); -Services.prefs.setCharPref(kPingUrlPref, kPingUrl); -Services.prefs.setBoolPref(kNewtabEnhancedPref, true); - -const kHttpHandlerData = {}; -kHttpHandlerData[kExamplePath] = {"directory": [{"url":"http://example.com", "title":"RemoteSource"}]}; - -const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", - "nsIBinaryInputStream", - "setInputStream"); - -var gLastRequestPath; - -var suggestedTile1 = { - url: "http://turbotax.com", - type: "affiliate", - lastVisitDate: 4, - adgroup_name: "Adgroup1", - frecent_sites: [ - "taxact.com", - "hrblock.com", - "1040.com", - "taxslayer.com" - ] -}; -var suggestedTile2 = { - url: "http://irs.gov", - type: "affiliate", - lastVisitDate: 3, - adgroup_name: "Adgroup2", - frecent_sites: [ - "taxact.com", - "hrblock.com", - "freetaxusa.com", - "taxslayer.com" - ] -}; -var suggestedTile3 = { - url: "http://hrblock.com", - type: "affiliate", - lastVisitDate: 2, - adgroup_name: "Adgroup3", - frecent_sites: [ - "taxact.com", - "freetaxusa.com", - "1040.com", - "taxslayer.com" - ] -}; -var suggestedTile4 = { - url: "http://sponsoredtile.com", - type: "sponsored", - lastVisitDate: 1, - adgroup_name: "Adgroup4", - frecent_sites: [ - "sponsoredtarget.com" - ] -} -var suggestedTile5 = { - url: "http://eviltile.com", - type: "affiliate", - lastVisitDate: 5, - explanation: "This is an evil tile <form><button formaction='javascript:alert(1)''>X</button></form> muhahaha", - adgroup_name: "WE ARE EVIL <link rel='import' href='test.svg'/>", - frecent_sites: [ - "eviltarget.com" - ] -} -var someOtherSite = {url: "http://someothersite.com", title: "Not_A_Suggested_Site"}; - -function getHttpHandler(path) { - let code = 200; - let body = JSON.stringify(kHttpHandlerData[path]); - if (path == kFailPath) { - code = 204; - } - return function(aRequest, aResponse) { - gLastRequestPath = aRequest.path; - aResponse.setStatusLine(null, code); - aResponse.setHeader("Content-Type", "application/json"); - aResponse.write(body); - }; -} - -function isIdentical(actual, expected) { - if (expected == null) { - do_check_eq(actual, expected); - } - else if (typeof expected == "object") { - // Make sure all the keys match up - do_check_eq(Object.keys(actual).sort() + "", Object.keys(expected).sort()); - - // Recursively check each value individually - Object.keys(expected).forEach(key => { - isIdentical(actual[key], expected[key]); - }); - } - else { - do_check_eq(actual, expected); - } -} - -function fetchData() { - let deferred = Promise.defer(); - - DirectoryLinksProvider.getLinks(linkData => { - deferred.resolve(linkData); - }); - return deferred.promise; -} - -function readJsonFile(jsonFile = DIRECTORY_LINKS_FILE) { - let decoder = new TextDecoder(); - let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, jsonFile); - return OS.File.read(directoryLinksFilePath).then(array => { - let json = decoder.decode(array); - return JSON.parse(json); - }, () => { return "" }); -} - -function cleanJsonFile(jsonFile = DIRECTORY_LINKS_FILE) { - let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.localProfileDir, jsonFile); - return OS.File.remove(directoryLinksFilePath); -} - -function LinksChangeObserver() { - this.deferred = Promise.defer(); - this.onManyLinksChanged = () => this.deferred.resolve(); - this.onDownloadFail = this.onManyLinksChanged; -} - -function promiseDirectoryDownloadOnPrefChange(pref, newValue) { - let oldValue = Services.prefs.getCharPref(pref); - if (oldValue != newValue) { - // if the preference value is already equal to newValue - // the pref service will not call our observer and we - // deadlock. Hence only setup observer if values differ - let observer = new LinksChangeObserver(); - DirectoryLinksProvider.addObserver(observer); - Services.prefs.setCharPref(pref, newValue); - return observer.deferred.promise.then(() => { - DirectoryLinksProvider.removeObserver(observer); - }); - } - return Promise.resolve(); -} - -function promiseSetupDirectoryLinksProvider(options = {}) { - return Task.spawn(function*() { - let linksURL = options.linksURL || kTestURL; - yield DirectoryLinksProvider.init(); - yield promiseDirectoryDownloadOnPrefChange(kLocalePref, options.locale || "en-US"); - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, linksURL); - do_check_eq(DirectoryLinksProvider._linksURL, linksURL); - DirectoryLinksProvider._lastDownloadMS = options.lastDownloadMS || 0; - }); -} - -function promiseCleanDirectoryLinksProvider() { - return Task.spawn(function*() { - yield promiseDirectoryDownloadOnPrefChange(kLocalePref, "en-US"); - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kTestURL); - yield DirectoryLinksProvider._clearFrequencyCap(); - yield DirectoryLinksProvider._loadInadjacentSites(); - DirectoryLinksProvider._lastDownloadMS = 0; - DirectoryLinksProvider.reset(); - }); -} - -function run_test() { - // Set up a mock HTTP server to serve a directory page - server = new HttpServer(); - server.registerPrefixHandler(kExamplePath, getHttpHandler(kExamplePath)); - server.registerPrefixHandler(kFailPath, getHttpHandler(kFailPath)); - server.start(kDefaultServerPort); - NewTabUtils.init(); - - run_next_test(); - - // Teardown. - do_register_cleanup(function() { - server.stop(function() { }); - DirectoryLinksProvider.reset(); - Services.prefs.clearUserPref(kLocalePref); - Services.prefs.clearUserPref(kSourceUrlPref); - Services.prefs.clearUserPref(kPingUrlPref); - Services.prefs.clearUserPref(kNewtabEnhancedPref); - }); -} - - -function setTimeout(fun, timeout) { - let timer = Components.classes["@mozilla.org/timer;1"] - .createInstance(Components.interfaces.nsITimer); - var event = { - notify: function () { - fun(); - } - }; - timer.initWithCallback(event, timeout, - Components.interfaces.nsITimer.TYPE_ONE_SHOT); - return timer; -} - -add_task(function test_shouldUpdateSuggestedTile() { - let suggestedLink = { - targetedSite: "somesite.com" - }; - - // DirectoryLinksProvider has no suggested tile and no top sites => no need to update - do_check_eq(DirectoryLinksProvider._getCurrentTopSiteCount(), 0); - isIdentical(NewTabUtils.getProviderLinks(), []); - do_check_eq(DirectoryLinksProvider._shouldUpdateSuggestedTile(), false); - - // DirectoryLinksProvider has a suggested tile and no top sites => need to update - let origGetProviderLinks = NewTabUtils.getProviderLinks; - NewTabUtils.getProviderLinks = (provider) => [suggestedLink]; - - do_check_eq(DirectoryLinksProvider._getCurrentTopSiteCount(), 0); - isIdentical(NewTabUtils.getProviderLinks(), [suggestedLink]); - do_check_eq(DirectoryLinksProvider._shouldUpdateSuggestedTile(), true); - - // DirectoryLinksProvider has a suggested tile and 8 top sites => no need to update - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => 8; - - do_check_eq(DirectoryLinksProvider._getCurrentTopSiteCount(), 8); - isIdentical(NewTabUtils.getProviderLinks(), [suggestedLink]); - do_check_eq(DirectoryLinksProvider._shouldUpdateSuggestedTile(), false); - - // DirectoryLinksProvider has no suggested tile and 8 top sites => need to update - NewTabUtils.getProviderLinks = origGetProviderLinks; - do_check_eq(DirectoryLinksProvider._getCurrentTopSiteCount(), 8); - isIdentical(NewTabUtils.getProviderLinks(), []); - do_check_eq(DirectoryLinksProvider._shouldUpdateSuggestedTile(), true); - - // Cleanup - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; -}); - -add_task(function* test_updateSuggestedTile() { - let topSites = ["site0.com", "1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"]; - - // Initial setup - let data = {"suggested": [suggestedTile1, suggestedTile2, suggestedTile3], "directory": [someOtherSite]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - - let testObserver = new TestFirstRun(); - DirectoryLinksProvider.addObserver(testObserver); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - let links = yield fetchData(); - - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = function(site) { - return topSites.indexOf(site) >= 0; - } - - let origGetProviderLinks = NewTabUtils.getProviderLinks; - NewTabUtils.getProviderLinks = function(provider) { - return links; - } - - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => 8; - - do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined); - - function TestFirstRun() { - this.promise = new Promise(resolve => { - this.onLinkChanged = (directoryLinksProvider, link) => { - links.unshift(link); - let possibleLinks = [suggestedTile1.url, suggestedTile2.url, suggestedTile3.url]; - - isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], ["hrblock.com", "1040.com", "freetaxusa.com"]); - do_check_true(possibleLinks.indexOf(link.url) > -1); - do_check_eq(link.frecency, SUGGESTED_FRECENCY); - do_check_eq(link.type, "affiliate"); - resolve(); - }; - }); - } - - function TestChangingSuggestedTile() { - this.count = 0; - this.promise = new Promise(resolve => { - this.onLinkChanged = (directoryLinksProvider, link) => { - this.count++; - let possibleLinks = [suggestedTile1.url, suggestedTile2.url, suggestedTile3.url]; - - do_check_true(possibleLinks.indexOf(link.url) > -1); - do_check_eq(link.type, "affiliate"); - do_check_true(this.count <= 2); - - if (this.count == 1) { - // The removed suggested link is the one we added initially. - do_check_eq(link.url, links.shift().url); - do_check_eq(link.frecency, SUGGESTED_FRECENCY); - } else { - links.unshift(link); - do_check_eq(link.frecency, SUGGESTED_FRECENCY); - } - isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], ["hrblock.com", "freetaxusa.com"]); - resolve(); - } - }); - } - - function TestRemovingSuggestedTile() { - this.count = 0; - this.promise = new Promise(resolve => { - this.onLinkChanged = (directoryLinksProvider, link) => { - this.count++; - - do_check_eq(link.type, "affiliate"); - do_check_eq(this.count, 1); - do_check_eq(link.frecency, SUGGESTED_FRECENCY); - do_check_eq(link.url, links.shift().url); - isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], []); - resolve(); - } - }); - } - - // Test first call to '_updateSuggestedTile()', called when fetching directory links. - yield testObserver.promise; - DirectoryLinksProvider.removeObserver(testObserver); - - // Removing a top site that doesn't have a suggested link should - // not change the current suggested tile. - let removedTopsite = topSites.shift(); - do_check_eq(removedTopsite, "site0.com"); - do_check_false(NewTabUtils.isTopPlacesSite(removedTopsite)); - let updateSuggestedTile = DirectoryLinksProvider._handleLinkChanged({ - url: "http://" + removedTopsite, - type: "history", - }); - do_check_false(updateSuggestedTile); - - // Removing a top site that has a suggested link should - // remove any current suggested tile and add a new one. - testObserver = new TestChangingSuggestedTile(); - DirectoryLinksProvider.addObserver(testObserver); - removedTopsite = topSites.shift(); - do_check_eq(removedTopsite, "1040.com"); - do_check_false(NewTabUtils.isTopPlacesSite(removedTopsite)); - DirectoryLinksProvider.onLinkChanged(DirectoryLinksProvider, { - url: "http://" + removedTopsite, - type: "history", - }); - yield testObserver.promise; - do_check_eq(testObserver.count, 2); - DirectoryLinksProvider.removeObserver(testObserver); - - // Removing all top sites with suggested links should remove - // the current suggested link and not replace it. - topSites = []; - testObserver = new TestRemovingSuggestedTile(); - DirectoryLinksProvider.addObserver(testObserver); - DirectoryLinksProvider.onManyLinksChanged(); - yield testObserver.promise; - - // Cleanup - yield promiseCleanDirectoryLinksProvider(); - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - NewTabUtils.getProviderLinks = origGetProviderLinks; - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; -}); - -add_task(function* test_suggestedLinksMap() { - let data = {"suggested": [suggestedTile1, suggestedTile2, suggestedTile3, suggestedTile4], "directory": [someOtherSite]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - let links = yield fetchData(); - - // Ensure the suggested tiles were not considered directory tiles. - do_check_eq(links.length, 1); - let expected_data = [{url: "http://someothersite.com", title: "Not_A_Suggested_Site", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}]; - isIdentical(links, expected_data); - - // Check for correctly saved suggested tiles data. - expected_data = { - "taxact.com": [suggestedTile1, suggestedTile2, suggestedTile3], - "hrblock.com": [suggestedTile1, suggestedTile2], - "1040.com": [suggestedTile1, suggestedTile3], - "taxslayer.com": [suggestedTile1, suggestedTile2, suggestedTile3], - "freetaxusa.com": [suggestedTile2, suggestedTile3], - "sponsoredtarget.com": [suggestedTile4], - }; - - let suggestedSites = [...DirectoryLinksProvider._suggestedLinks.keys()]; - do_check_eq(suggestedSites.indexOf("sponsoredtarget.com"), 5); - do_check_eq(suggestedSites.length, Object.keys(expected_data).length); - - DirectoryLinksProvider._suggestedLinks.forEach((suggestedLinks, site) => { - let suggestedLinksItr = suggestedLinks.values(); - for (let link of expected_data[site]) { - let linkCopy = JSON.parse(JSON.stringify(link)); - linkCopy.targetedName = link.adgroup_name; - linkCopy.explanation = ""; - isIdentical(suggestedLinksItr.next().value, linkCopy); - } - }) - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_topSitesWithSuggestedLinks() { - let topSites = ["site0.com", "1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"]; - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = function(site) { - return topSites.indexOf(site) >= 0; - } - - // Mock out getProviderLinks() so we don't have to populate cache in NewTabUtils - let origGetProviderLinks = NewTabUtils.getProviderLinks; - NewTabUtils.getProviderLinks = function(provider) { - return []; - } - - // We start off with no top sites with suggested links. - do_check_eq(DirectoryLinksProvider._topSitesWithSuggestedLinks.size, 0); - - let data = {"suggested": [suggestedTile1, suggestedTile2, suggestedTile3], "directory": [someOtherSite]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - yield fetchData(); - - // Check we've populated suggested links as expected. - do_check_eq(DirectoryLinksProvider._suggestedLinks.size, 5); - - // When many sites change, we update _topSitesWithSuggestedLinks as expected. - let expectedTopSitesWithSuggestedLinks = ["hrblock.com", "1040.com", "freetaxusa.com"]; - DirectoryLinksProvider._handleManyLinksChanged(); - isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], expectedTopSitesWithSuggestedLinks); - - // Removing site6.com as a topsite has no impact on _topSitesWithSuggestedLinks. - let popped = topSites.pop(); - DirectoryLinksProvider._handleLinkChanged({url: "http://" + popped}); - isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], expectedTopSitesWithSuggestedLinks); - - // Removing freetaxusa.com as a topsite will remove it from _topSitesWithSuggestedLinks. - popped = topSites.pop(); - expectedTopSitesWithSuggestedLinks.pop(); - DirectoryLinksProvider._handleLinkChanged({url: "http://" + popped}); - isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], expectedTopSitesWithSuggestedLinks); - - // Re-adding freetaxusa.com as a topsite will add it to _topSitesWithSuggestedLinks. - topSites.push(popped); - expectedTopSitesWithSuggestedLinks.push(popped); - DirectoryLinksProvider._handleLinkChanged({url: "http://" + popped}); - isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], expectedTopSitesWithSuggestedLinks); - - // Cleanup. - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - NewTabUtils.getProviderLinks = origGetProviderLinks; -}); - -add_task(function* test_suggestedAttributes() { - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = () => true; - - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => 8; - - let frecent_sites = "addons.mozilla.org,air.mozilla.org,blog.mozilla.org,bugzilla.mozilla.org,developer.mozilla.org,etherpad.mozilla.org,forums.mozillazine.org,hacks.mozilla.org,hg.mozilla.org,mozilla.org,planet.mozilla.org,quality.mozilla.org,support.mozilla.org,treeherder.mozilla.org,wiki.mozilla.org".split(","); - let imageURI = "https://image/"; - let title = "the title"; - let type = "affiliate"; - let url = "http://test.url/"; - let adgroup_name = "Mozilla"; - let data = { - suggested: [{ - frecent_sites, - imageURI, - title, - type, - url, - adgroup_name - }] - }; - let dataURI = "data:application/json," + escape(JSON.stringify(data)); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - // Wait for links to get loaded - let gLinks = NewTabUtils.links; - gLinks.addProvider(DirectoryLinksProvider); - gLinks.populateCache(); - yield new Promise(resolve => { - NewTabUtils.allPages.register({ - observe: _ => _, - update() { - NewTabUtils.allPages.unregister(this); - resolve(); - } - }); - }); - - // Make sure we get the expected attributes on the suggested tile - let link = gLinks.getLinks()[0]; - do_check_eq(link.imageURI, imageURI); - do_check_eq(link.targetedName, "Mozilla"); - do_check_eq(link.targetedSite, frecent_sites[0]); - do_check_eq(link.title, title); - do_check_eq(link.type, type); - do_check_eq(link.url, url); - - // Cleanup. - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; - gLinks.removeProvider(DirectoryLinksProvider); - DirectoryLinksProvider.removeObserver(gLinks); -}); - -add_task(function* test_frequencyCappedSites_views() { - Services.prefs.setCharPref(kPingUrlPref, ""); - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = () => true; - - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => 8; - - let testUrl = "http://frequency.capped/link"; - let targets = ["top.site.com"]; - let data = { - suggested: [{ - type: "affiliate", - frecent_sites: targets, - url: testUrl, - frequency_caps: {daily: 5}, - adgroup_name: "Test" - }], - directory: [{ - type: "organic", - url: "http://directory.site/" - }] - }; - let dataURI = "data:application/json," + JSON.stringify(data); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - // Wait for links to get loaded - let gLinks = NewTabUtils.links; - gLinks.addProvider(DirectoryLinksProvider); - gLinks.populateCache(); - yield new Promise(resolve => { - NewTabUtils.allPages.register({ - observe: _ => _, - update() { - NewTabUtils.allPages.unregister(this); - resolve(); - } - }); - }); - - function synthesizeAction(action) { - DirectoryLinksProvider.reportSitesAction([{ - link: { - targetedSite: targets[0], - url: testUrl - } - }], action, 0); - } - - function checkFirstTypeAndLength(type, length) { - let links = gLinks.getLinks(); - do_check_eq(links[0].type, type); - do_check_eq(links.length, length); - } - - // Make sure we get 5 views of the link before it is removed - checkFirstTypeAndLength("affiliate", 2); - synthesizeAction("view"); - checkFirstTypeAndLength("affiliate", 2); - synthesizeAction("view"); - checkFirstTypeAndLength("affiliate", 2); - synthesizeAction("view"); - checkFirstTypeAndLength("affiliate", 2); - synthesizeAction("view"); - checkFirstTypeAndLength("affiliate", 2); - synthesizeAction("view"); - checkFirstTypeAndLength("organic", 1); - - // Cleanup. - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; - gLinks.removeProvider(DirectoryLinksProvider); - DirectoryLinksProvider.removeObserver(gLinks); - Services.prefs.setCharPref(kPingUrlPref, kPingUrl); -}); - -add_task(function* test_frequencyCappedSites_click() { - Services.prefs.setCharPref(kPingUrlPref, ""); - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = () => true; - - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => 8; - - let testUrl = "http://frequency.capped/link"; - let targets = ["top.site.com"]; - let data = { - suggested: [{ - type: "affiliate", - frecent_sites: targets, - url: testUrl, - adgroup_name: "Test" - }], - directory: [{ - type: "organic", - url: "http://directory.site/" - }] - }; - let dataURI = "data:application/json," + JSON.stringify(data); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - // Wait for links to get loaded - let gLinks = NewTabUtils.links; - gLinks.addProvider(DirectoryLinksProvider); - gLinks.populateCache(); - yield new Promise(resolve => { - NewTabUtils.allPages.register({ - observe: _ => _, - update() { - NewTabUtils.allPages.unregister(this); - resolve(); - } - }); - }); - - function synthesizeAction(action) { - DirectoryLinksProvider.reportSitesAction([{ - link: { - targetedSite: targets[0], - url: testUrl - } - }], action, 0); - } - - function checkFirstTypeAndLength(type, length) { - let links = gLinks.getLinks(); - do_check_eq(links[0].type, type); - do_check_eq(links.length, length); - } - - // Make sure the link disappears after the first click - checkFirstTypeAndLength("affiliate", 2); - synthesizeAction("view"); - checkFirstTypeAndLength("affiliate", 2); - synthesizeAction("click"); - checkFirstTypeAndLength("organic", 1); - - // Cleanup. - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; - gLinks.removeProvider(DirectoryLinksProvider); - DirectoryLinksProvider.removeObserver(gLinks); - Services.prefs.setCharPref(kPingUrlPref, kPingUrl); -}); - -add_task(function* test_fetchAndCacheLinks_local() { - yield DirectoryLinksProvider.init(); - yield cleanJsonFile(); - // Trigger cache of data or chrome uri files in profD - yield DirectoryLinksProvider._fetchAndCacheLinks(kTestURL); - let data = yield readJsonFile(); - isIdentical(data, kURLData); -}); - -add_task(function* test_fetchAndCacheLinks_remote() { - yield DirectoryLinksProvider.init(); - yield cleanJsonFile(); - // this must trigger directory links json download and save it to cache file - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kExampleURL + "%LOCALE%"); - do_check_eq(gLastRequestPath, kExamplePath + "en-US"); - let data = yield readJsonFile(); - isIdentical(data, kHttpHandlerData[kExamplePath]); -}); - -add_task(function* test_fetchAndCacheLinks_malformedURI() { - yield DirectoryLinksProvider.init(); - yield cleanJsonFile(); - let someJunk = "some junk"; - try { - yield DirectoryLinksProvider._fetchAndCacheLinks(someJunk); - do_throw("Malformed URIs should fail") - } catch (e) { - do_check_eq(e, "Error fetching " + someJunk) - } - - // File should be empty. - let data = yield readJsonFile(); - isIdentical(data, ""); -}); - -add_task(function* test_fetchAndCacheLinks_unknownHost() { - yield DirectoryLinksProvider.init(); - yield cleanJsonFile(); - let nonExistentServer = "http://localhost:56789/"; - try { - yield DirectoryLinksProvider._fetchAndCacheLinks(nonExistentServer); - do_throw("BAD URIs should fail"); - } catch (e) { - do_check_true(e.startsWith("Fetching " + nonExistentServer + " results in error code: ")) - } - - // File should be empty. - let data = yield readJsonFile(); - isIdentical(data, ""); -}); - -add_task(function* test_fetchAndCacheLinks_non200Status() { - yield DirectoryLinksProvider.init(); - yield cleanJsonFile(); - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kFailURL); - do_check_eq(gLastRequestPath, kFailPath); - let data = yield readJsonFile(); - isIdentical(data, {}); -}); - -// To test onManyLinksChanged observer, trigger a fetch -add_task(function* test_DirectoryLinksProvider__linkObservers() { - yield DirectoryLinksProvider.init(); - - let testObserver = new LinksChangeObserver(); - DirectoryLinksProvider.addObserver(testObserver); - do_check_eq(DirectoryLinksProvider._observers.size, 1); - DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true); - - yield testObserver.deferred.promise; - DirectoryLinksProvider._removeObservers(); - do_check_eq(DirectoryLinksProvider._observers.size, 0); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider__prefObserver_url() { - yield promiseSetupDirectoryLinksProvider({linksURL: kTestURL}); - - let links = yield fetchData(); - do_check_eq(links.length, 1); - let expectedData = [{url: "http://example.com", title: "LocalSource", frecency: DIRECTORY_FRECENCY, lastVisitDate: 1}]; - isIdentical(links, expectedData); - - // tests these 2 things: - // 1. _linksURL is properly set after the pref change - // 2. invalid source url is correctly handled - let exampleUrl = 'http://localhost:56789/bad'; - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, exampleUrl); - do_check_eq(DirectoryLinksProvider._linksURL, exampleUrl); - - // since the download fail, the directory file must remain the same - let newLinks = yield fetchData(); - isIdentical(newLinks, expectedData); - - // now remove the file, and re-download - yield cleanJsonFile(); - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, exampleUrl + " "); - // we now should see empty links - newLinks = yield fetchData(); - isIdentical(newLinks, []); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_getLinks_noDirectoryData() { - let data = { - "directory": [], - }; - let dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - let links = yield fetchData(); - do_check_eq(links.length, 0); - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_getLinks_badData() { - let data = { - "en-US": { - "en-US": [{url: "http://example.com", title: "US"}], - }, - }; - let dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - // Make sure we get nothing for incorrectly formatted data - let links = yield fetchData(); - do_check_eq(links.length, 0); - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function test_DirectoryLinksProvider_needsDownload() { - // test timestamping - DirectoryLinksProvider._lastDownloadMS = 0; - do_check_true(DirectoryLinksProvider._needsDownload); - DirectoryLinksProvider._lastDownloadMS = Date.now(); - do_check_false(DirectoryLinksProvider._needsDownload); - DirectoryLinksProvider._lastDownloadMS = Date.now() - (60*60*24 + 1)*1000; - do_check_true(DirectoryLinksProvider._needsDownload); - DirectoryLinksProvider._lastDownloadMS = 0; -}); - -add_task(function* test_DirectoryLinksProvider_fetchAndCacheLinksIfNecessary() { - yield DirectoryLinksProvider.init(); - yield cleanJsonFile(); - // explicitly change source url to cause the download during setup - yield promiseSetupDirectoryLinksProvider({linksURL: kTestURL+" "}); - yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(); - - // inspect lastDownloadMS timestamp which should be 5 seconds less then now() - let lastDownloadMS = DirectoryLinksProvider._lastDownloadMS; - do_check_true((Date.now() - lastDownloadMS) < 5000); - - // we should have fetched a new file during setup - let data = yield readJsonFile(); - isIdentical(data, kURLData); - - // attempt to download again - the timestamp should not change - yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(); - do_check_eq(DirectoryLinksProvider._lastDownloadMS, lastDownloadMS); - - // clean the file and force the download - yield cleanJsonFile(); - yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true); - data = yield readJsonFile(); - isIdentical(data, kURLData); - - // make sure that failed download does not corrupt the file, nor changes lastDownloadMS - lastDownloadMS = DirectoryLinksProvider._lastDownloadMS; - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, "http://"); - yield DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true); - data = yield readJsonFile(); - isIdentical(data, kURLData); - do_check_eq(DirectoryLinksProvider._lastDownloadMS, lastDownloadMS); - - // _fetchAndCacheLinksIfNecessary must return same promise if download is in progress - let downloadPromise = DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true); - let anotherPromise = DirectoryLinksProvider._fetchAndCacheLinksIfNecessary(true); - do_check_true(downloadPromise === anotherPromise); - yield downloadPromise; - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_fetchDirectoryOnPrefChange() { - yield DirectoryLinksProvider.init(); - - let testObserver = new LinksChangeObserver(); - DirectoryLinksProvider.addObserver(testObserver); - - yield cleanJsonFile(); - // ensure that provider does not think it needs to download - do_check_false(DirectoryLinksProvider._needsDownload); - - // change the source URL, which should force directory download - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, kExampleURL); - // then wait for testObserver to fire and test that json is downloaded - yield testObserver.deferred.promise; - do_check_eq(gLastRequestPath, kExamplePath); - let data = yield readJsonFile(); - isIdentical(data, kHttpHandlerData[kExamplePath]); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_fetchDirectoryOnShow() { - yield promiseSetupDirectoryLinksProvider(); - - // set lastdownload to 0 to make DirectoryLinksProvider want to download - DirectoryLinksProvider._lastDownloadMS = 0; - do_check_true(DirectoryLinksProvider._needsDownload); - - // download should happen on view - yield DirectoryLinksProvider.reportSitesAction([], "view"); - do_check_true(DirectoryLinksProvider._lastDownloadMS != 0); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_fetchDirectoryOnInit() { - // ensure preferences are set to defaults - yield promiseSetupDirectoryLinksProvider(); - // now clean to provider, so we can init it again - yield promiseCleanDirectoryLinksProvider(); - - yield cleanJsonFile(); - yield DirectoryLinksProvider.init(); - let data = yield readJsonFile(); - isIdentical(data, kURLData); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_getLinksFromCorruptedFile() { - yield promiseSetupDirectoryLinksProvider(); - - // write bogus json to a file and attempt to fetch from it - let directoryLinksFilePath = OS.Path.join(OS.Constants.Path.profileDir, DIRECTORY_LINKS_FILE); - yield OS.File.writeAtomic(directoryLinksFilePath, '{"en-US":'); - let data = yield fetchData(); - isIdentical(data, []); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_getAllowedLinks() { - let data = {"directory": [ - {url: "ftp://example.com"}, - {url: "http://example.net"}, - {url: "javascript:5"}, - {url: "https://example.com"}, - {url: "httpJUNKjavascript:42"}, - {url: "data:text/plain,hi"}, - {url: "http/bork:eh"}, - ]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - let links = yield fetchData(); - do_check_eq(links.length, 2); - - // The only remaining url should be http and https - do_check_eq(links[0].url, data["directory"][1].url); - do_check_eq(links[1].url, data["directory"][3].url); -}); - -add_task(function* test_DirectoryLinksProvider_getAllowedImages() { - let data = {"directory": [ - {url: "http://example.com", imageURI: "ftp://example.com"}, - {url: "http://example.com", imageURI: "http://example.net"}, - {url: "http://example.com", imageURI: "javascript:5"}, - {url: "http://example.com", imageURI: "https://example.com"}, - {url: "http://example.com", imageURI: "httpJUNKjavascript:42"}, - {url: "http://example.com", imageURI: "data:text/plain,hi"}, - {url: "http://example.com", imageURI: "http/bork:eh"}, - ]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - let links = yield fetchData(); - do_check_eq(links.length, 2); - - // The only remaining images should be https and data - do_check_eq(links[0].imageURI, data["directory"][3].imageURI); - do_check_eq(links[1].imageURI, data["directory"][5].imageURI); -}); - -add_task(function* test_DirectoryLinksProvider_getAllowedImages_base() { - let data = {"directory": [ - {url: "http://example1.com", imageURI: "https://example.com"}, - {url: "http://example2.com", imageURI: "https://tiles.cdn.mozilla.net"}, - {url: "http://example3.com", imageURI: "https://tiles2.cdn.mozilla.net"}, - {url: "http://example4.com", enhancedImageURI: "https://mozilla.net"}, - {url: "http://example5.com", imageURI: "data:text/plain,hi"}, - ]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - // Pretend we're using the default pref to trigger base matching - DirectoryLinksProvider.__linksURLModified = false; - - let links = yield fetchData(); - do_check_eq(links.length, 4); - - // The only remaining images should be https with mozilla.net or data URI - do_check_eq(links[0].url, data["directory"][1].url); - do_check_eq(links[1].url, data["directory"][2].url); - do_check_eq(links[2].url, data["directory"][3].url); - do_check_eq(links[3].url, data["directory"][4].url); -}); - -add_task(function* test_DirectoryLinksProvider_getAllowedEnhancedImages() { - let data = {"directory": [ - {url: "http://example.com", enhancedImageURI: "ftp://example.com"}, - {url: "http://example.com", enhancedImageURI: "http://example.net"}, - {url: "http://example.com", enhancedImageURI: "javascript:5"}, - {url: "http://example.com", enhancedImageURI: "https://example.com"}, - {url: "http://example.com", enhancedImageURI: "httpJUNKjavascript:42"}, - {url: "http://example.com", enhancedImageURI: "data:text/plain,hi"}, - {url: "http://example.com", enhancedImageURI: "http/bork:eh"}, - ]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - let links = yield fetchData(); - do_check_eq(links.length, 2); - - // The only remaining enhancedImages should be http and https and data - do_check_eq(links[0].enhancedImageURI, data["directory"][3].enhancedImageURI); - do_check_eq(links[1].enhancedImageURI, data["directory"][5].enhancedImageURI); -}); - -add_task(function* test_DirectoryLinksProvider_getEnhancedLink() { - let data = {"enhanced": [ - {url: "http://example.net", enhancedImageURI: "data:,net1"}, - {url: "http://example.com", enhancedImageURI: "data:,com1"}, - {url: "http://example.com", enhancedImageURI: "data:,com2"}, - ]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - let links = yield fetchData(); - do_check_eq(links.length, 0); // There are no directory links. - - function checkEnhanced(url, image) { - let enhanced = DirectoryLinksProvider.getEnhancedLink({url: url}); - do_check_eq(enhanced && enhanced.enhancedImageURI, image); - } - - // Get the expected image for the same site - checkEnhanced("http://example.net/", "data:,net1"); - checkEnhanced("http://example.net/path", "data:,net1"); - checkEnhanced("https://www.example.net/", "data:,net1"); - checkEnhanced("https://www3.example.net/", "data:,net1"); - - // Get the image of the last entry - checkEnhanced("http://example.com", "data:,com2"); - - // Get the inline enhanced image - let inline = DirectoryLinksProvider.getEnhancedLink({ - url: "http://example.com/echo", - enhancedImageURI: "data:,echo", - }); - do_check_eq(inline.enhancedImageURI, "data:,echo"); - do_check_eq(inline.url, "http://example.com/echo"); - - // Undefined for not enhanced - checkEnhanced("http://sub.example.net/", undefined); - checkEnhanced("http://example.org", undefined); - checkEnhanced("http://localhost", undefined); - checkEnhanced("http://127.0.0.1", undefined); - - // Make sure old data is not cached - data = {"enhanced": [ - {url: "http://example.com", enhancedImageURI: "data:,fresh"}, - ]}; - dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - links = yield fetchData(); - do_check_eq(links.length, 0); // There are no directory links. - checkEnhanced("http://example.net", undefined); - checkEnhanced("http://example.com", "data:,fresh"); -}); - -add_task(function* test_DirectoryLinksProvider_enhancedURIs() { - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = () => true; - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => 8; - - let data = { - "suggested": [ - {url: "http://example.net", enhancedImageURI: "data:,net1", title:"SuggestedTitle", adgroup_name: "Test", frecent_sites: ["test.com"]} - ], - "directory": [ - {url: "http://example.net", enhancedImageURI: "data:,net2", title:"DirectoryTitle"} - ] - }; - let dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - - // Wait for links to get loaded - let gLinks = NewTabUtils.links; - gLinks.addProvider(DirectoryLinksProvider); - gLinks.populateCache(); - yield new Promise(resolve => { - NewTabUtils.allPages.register({ - observe: _ => _, - update() { - NewTabUtils.allPages.unregister(this); - resolve(); - } - }); - }); - - // Check that we've saved the directory tile. - let links = yield fetchData(); - do_check_eq(links.length, 1); - do_check_eq(links[0].title, "DirectoryTitle"); - do_check_eq(links[0].enhancedImageURI, "data:,net2"); - - // Check that the suggested tile with the same URL replaces the directory tile. - links = gLinks.getLinks(); - do_check_eq(links.length, 1); - do_check_eq(links[0].title, "SuggestedTitle"); - do_check_eq(links[0].enhancedImageURI, "data:,net1"); - - // Cleanup. - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; - gLinks.removeProvider(DirectoryLinksProvider); -}); - -add_task(function test_DirectoryLinksProvider_setDefaultEnhanced() { - function checkDefault(expected) { - Services.prefs.clearUserPref(kNewtabEnhancedPref); - do_check_eq(Services.prefs.getBoolPref(kNewtabEnhancedPref), expected); - } - - // Use the default donottrack prefs (enabled = false) - Services.prefs.clearUserPref("privacy.donottrackheader.enabled"); - checkDefault(true); - - // Turn on DNT - no track - Services.prefs.setBoolPref("privacy.donottrackheader.enabled", true); - checkDefault(false); - - // Turn off DNT header - Services.prefs.clearUserPref("privacy.donottrackheader.enabled"); - checkDefault(true); - - // Clean up - Services.prefs.clearUserPref("privacy.donottrackheader.value"); -}); - -add_task(function* test_timeSensetiveSuggestedTiles() { - // make tile json with start and end dates - let testStartTime = Date.now(); - // start date is now + 1 seconds - let startDate = new Date(testStartTime + 1000); - // end date is now + 3 seconds - let endDate = new Date(testStartTime + 3000); - let suggestedTile = Object.assign({ - time_limits: { - start: startDate.toISOString(), - end: endDate.toISOString(), - } - }, suggestedTile1); - - // Initial setup - let topSites = ["site0.com", "1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"]; - let data = {"suggested": [suggestedTile], "directory": [someOtherSite]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - - let testObserver = new TestTimingRun(); - DirectoryLinksProvider.addObserver(testObserver); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - let links = yield fetchData(); - - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = function(site) { - return topSites.indexOf(site) >= 0; - } - - let origGetProviderLinks = NewTabUtils.getProviderLinks; - NewTabUtils.getProviderLinks = function(provider) { - return links; - } - - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => 8; - - do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined); - - // this tester will fire twice: when start limit is reached and when tile link - // is removed upon end of the campaign, in which case deleteFlag will be set - function TestTimingRun() { - this.promise = new Promise(resolve => { - this.onLinkChanged = (directoryLinksProvider, link, ignoreFlag, deleteFlag) => { - // if we are not deleting, add link to links, so we can catch it's removal - if (!deleteFlag) { - links.unshift(link); - } - - isIdentical([...DirectoryLinksProvider._topSitesWithSuggestedLinks], ["hrblock.com", "1040.com"]); - do_check_eq(link.frecency, SUGGESTED_FRECENCY); - do_check_eq(link.type, "affiliate"); - do_check_eq(link.url, suggestedTile.url); - let timeDelta = Date.now() - testStartTime; - if (!deleteFlag) { - // this is start timeout corresponding to campaign start - // a seconds must pass and targetedSite must be set - do_print("TESTING START timeDelta: " + timeDelta); - do_check_true(timeDelta >= 1000 / 2); // check for at least half time - do_check_eq(link.targetedSite, "hrblock.com"); - do_check_true(DirectoryLinksProvider._campaignTimeoutID); - } - else { - // this is the campaign end timeout, so 3 seconds must pass - // and timeout should be cleared - do_print("TESTING END timeDelta: " + timeDelta); - do_check_true(timeDelta >= 3000 / 2); // check for at least half time - do_check_false(link.targetedSite); - do_check_false(DirectoryLinksProvider._campaignTimeoutID); - resolve(); - } - }; - }); - } - - // _updateSuggestedTile() is called when fetching directory links. - yield testObserver.promise; - DirectoryLinksProvider.removeObserver(testObserver); - - // shoudl suggest nothing - do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined); - - // set links back to contain directory tile only - links.shift(); - - // drop the end time - we should pick up the tile - suggestedTile.time_limits.end = null; - data = {"suggested": [suggestedTile], "directory": [someOtherSite]}; - dataURI = 'data:application/json,' + JSON.stringify(data); - - // redownload json and getLinks to force time recomputation - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, dataURI); - - // ensure that there's a link returned by _updateSuggestedTile and no timeout - let deferred = Promise.defer(); - DirectoryLinksProvider.getLinks(() => { - let link = DirectoryLinksProvider._updateSuggestedTile(); - // we should have a suggested tile and no timeout - do_check_eq(link.type, "affiliate"); - do_check_eq(link.url, suggestedTile.url); - do_check_false(DirectoryLinksProvider._campaignTimeoutID); - deferred.resolve(); - }); - yield deferred.promise; - - // repeat the test for end time only - suggestedTile.time_limits.start = null; - suggestedTile.time_limits.end = (new Date(Date.now() + 3000)).toISOString(); - - data = {"suggested": [suggestedTile], "directory": [someOtherSite]}; - dataURI = 'data:application/json,' + JSON.stringify(data); - - // redownload json and call getLinks() to force time recomputation - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, dataURI); - - // ensure that there's a link returned by _updateSuggestedTile and timeout set - deferred = Promise.defer(); - DirectoryLinksProvider.getLinks(() => { - let link = DirectoryLinksProvider._updateSuggestedTile(); - // we should have a suggested tile and timeout set - do_check_eq(link.type, "affiliate"); - do_check_eq(link.url, suggestedTile.url); - do_check_true(DirectoryLinksProvider._campaignTimeoutID); - DirectoryLinksProvider._clearCampaignTimeout(); - deferred.resolve(); - }); - yield deferred.promise; - - // Cleanup - yield promiseCleanDirectoryLinksProvider(); - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - NewTabUtils.getProviderLinks = origGetProviderLinks; - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; -}); - -add_task(function test_setupStartEndTime() { - let currentTime = Date.now(); - let dt = new Date(currentTime); - let link = { - time_limits: { - start: dt.toISOString() - } - }; - - // test ISO translation - DirectoryLinksProvider._setupStartEndTime(link); - do_check_eq(link.startTime, currentTime); - - // test localtime translation - let shiftedDate = new Date(currentTime - dt.getTimezoneOffset()*60*1000); - link.time_limits.start = shiftedDate.toISOString().replace(/Z$/, ""); - - DirectoryLinksProvider._setupStartEndTime(link); - do_check_eq(link.startTime, currentTime); - - // throw some garbage into date string - delete link.startTime; - link.time_limits.start = "no date" - DirectoryLinksProvider._setupStartEndTime(link); - do_check_false(link.startTime); - - link.time_limits.start = "2015-99999-01T00:00:00" - DirectoryLinksProvider._setupStartEndTime(link); - do_check_false(link.startTime); - - link.time_limits.start = "20150501T00:00:00" - DirectoryLinksProvider._setupStartEndTime(link); - do_check_false(link.startTime); -}); - -add_task(function* test_DirectoryLinksProvider_frequencyCapSetup() { - yield promiseSetupDirectoryLinksProvider(); - yield DirectoryLinksProvider.init(); - - yield promiseCleanDirectoryLinksProvider(); - yield DirectoryLinksProvider._readFrequencyCapFile(); - isIdentical(DirectoryLinksProvider._frequencyCaps, {}); - - // setup few links - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "1", - }); - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "2", - frequency_caps: {daily: 1, total: 2} - }); - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "3", - frequency_caps: {total: 2} - }); - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "4", - frequency_caps: {daily: 1} - }); - let freqCapsObject = DirectoryLinksProvider._frequencyCaps; - let capObject = freqCapsObject["1"]; - let defaultDaily = capObject.dailyCap; - let defaultTotal = capObject.totalCap; - // check if we have defaults set - do_check_true(capObject.dailyCap > 0); - do_check_true(capObject.totalCap > 0); - // check if defaults are properly handled - do_check_eq(freqCapsObject["2"].dailyCap, 1); - do_check_eq(freqCapsObject["2"].totalCap, 2); - do_check_eq(freqCapsObject["3"].dailyCap, defaultDaily); - do_check_eq(freqCapsObject["3"].totalCap, 2); - do_check_eq(freqCapsObject["4"].dailyCap, 1); - do_check_eq(freqCapsObject["4"].totalCap, defaultTotal); - - // write object to file - yield DirectoryLinksProvider._writeFrequencyCapFile(); - // empty out freqCapsObject and read file back - DirectoryLinksProvider._frequencyCaps = {}; - yield DirectoryLinksProvider._readFrequencyCapFile(); - // re-ran tests - they should all pass - do_check_eq(freqCapsObject["2"].dailyCap, 1); - do_check_eq(freqCapsObject["2"].totalCap, 2); - do_check_eq(freqCapsObject["3"].dailyCap, defaultDaily); - do_check_eq(freqCapsObject["3"].totalCap, 2); - do_check_eq(freqCapsObject["4"].dailyCap, 1); - do_check_eq(freqCapsObject["4"].totalCap, defaultTotal); - - // wait a second and prune frequency caps - yield new Promise(resolve => { - setTimeout(resolve, 1100); - }); - - // update one link and create another - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "3", - frequency_caps: {daily: 1, total: 2} - }); - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "7", - frequency_caps: {daily: 1, total: 2} - }); - // now prune the ones that have been in the object longer than 1 second - DirectoryLinksProvider._pruneFrequencyCapUrls(1000); - // make sure all keys but "3" and "7" are deleted - Object.keys(DirectoryLinksProvider._frequencyCaps).forEach(key => { - do_check_true(key == "3" || key == "7"); - }); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_getFrequencyCapLogic() { - yield promiseSetupDirectoryLinksProvider(); - yield DirectoryLinksProvider.init(); - - // setup suggested links - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "1", - frequency_caps: {daily: 2, total: 4} - }); - - do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1")); - // exhaust daily views - DirectoryLinksProvider._addFrequencyCapView("1") - do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1")); - DirectoryLinksProvider._addFrequencyCapView("1") - do_check_false(DirectoryLinksProvider._testFrequencyCapLimits("1")); - - // now step into the furture - let _wasTodayOrig = DirectoryLinksProvider._wasToday; - DirectoryLinksProvider._wasToday = function () { return false; } - // exhaust total views - DirectoryLinksProvider._addFrequencyCapView("1") - do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1")); - DirectoryLinksProvider._addFrequencyCapView("1") - // reached totalViews 4, should return false - do_check_false(DirectoryLinksProvider._testFrequencyCapLimits("1")); - - // add more views by updating configuration - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "1", - frequency_caps: {daily: 5, total: 10} - }); - // should be true, since we have more total views - do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("1")); - - // set click flag - DirectoryLinksProvider._setFrequencyCapClick("1"); - // always false after click - do_check_false(DirectoryLinksProvider._testFrequencyCapLimits("1")); - - // use unknown urls and ensure nothing breaks - DirectoryLinksProvider._addFrequencyCapView("nosuch.url"); - DirectoryLinksProvider._setFrequencyCapClick("nosuch.url"); - // testing unknown url should always return false - do_check_false(DirectoryLinksProvider._testFrequencyCapLimits("nosuch.url")); - - // reset _wasToday back to original function - DirectoryLinksProvider._wasToday = _wasTodayOrig; - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_getFrequencyCapReportSiteAction() { - yield promiseSetupDirectoryLinksProvider(); - yield DirectoryLinksProvider.init(); - - // setup suggested links - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "bar.com", - frequency_caps: {daily: 2, total: 4} - }); - - do_check_true(DirectoryLinksProvider._testFrequencyCapLimits("bar.com")); - // report site action - yield DirectoryLinksProvider.reportSitesAction([{ - link: { - targetedSite: "foo.com", - url: "bar.com" - }, - isPinned: function() { return false; }, - }], "view", 0); - - // read file content and ensure that view counters are updated - let data = yield readJsonFile(DirectoryLinksProvider._frequencyCapFilePath); - do_check_eq(data["bar.com"].dailyViews, 1); - do_check_eq(data["bar.com"].totalViews, 1); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_DirectoryLinksProvider_ClickRemoval() { - yield promiseSetupDirectoryLinksProvider(); - yield DirectoryLinksProvider.init(); - let landingUrl = "http://foo.com"; - - // setup suggested links - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: landingUrl, - frequency_caps: {daily: 2, total: 4} - }); - - // add views - DirectoryLinksProvider._addFrequencyCapView(landingUrl) - DirectoryLinksProvider._addFrequencyCapView(landingUrl) - // make a click - DirectoryLinksProvider._setFrequencyCapClick(landingUrl); - - // views must be 2 and click must be set - do_check_eq(DirectoryLinksProvider._frequencyCaps[landingUrl].totalViews, 2); - do_check_true(DirectoryLinksProvider._frequencyCaps[landingUrl].clicked); - - // now insert a visit into places - yield new Promise(resolve => { - PlacesUtils.asyncHistory.updatePlaces( - { - uri: NetUtil.newURI(landingUrl), - title: "HELLO", - visits: [{ - visitDate: Date.now()*1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK - }] - }, - { - handleError: function () { do_check_true(false); }, - handleResult: function () {}, - handleCompletion: function () { resolve(); } - } - ); - }); - - function UrlDeletionTester() { - this.promise = new Promise(resolve => { - this.onDeleteURI = (directoryLinksProvider, link) => { - resolve(); - }; - this.onClearHistory = (directoryLinksProvider) => { - resolve(); - }; - }); - } - - let testObserver = new UrlDeletionTester(); - DirectoryLinksProvider.addObserver(testObserver); - - PlacesUtils.bhistory.removePage(NetUtil.newURI(landingUrl)); - yield testObserver.promise; - DirectoryLinksProvider.removeObserver(testObserver); - // views must be 2 and click should not exist - do_check_eq(DirectoryLinksProvider._frequencyCaps[landingUrl].totalViews, 2); - do_check_false(DirectoryLinksProvider._frequencyCaps[landingUrl].hasOwnProperty("clicked")); - - // verify that disk written data is kosher - let data = yield readJsonFile(DirectoryLinksProvider._frequencyCapFilePath); - do_check_eq(data[landingUrl].totalViews, 2); - do_check_false(data[landingUrl].hasOwnProperty("clicked")); - - // now test clear history - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: landingUrl, - frequency_caps: {daily: 2, total: 4} - }); - DirectoryLinksProvider._updateFrequencyCapSettings({ - url: "http://bar.com", - frequency_caps: {daily: 2, total: 4} - }); - - DirectoryLinksProvider._setFrequencyCapClick(landingUrl); - DirectoryLinksProvider._setFrequencyCapClick("http://bar.com"); - // both tiles must have clicked - do_check_true(DirectoryLinksProvider._frequencyCaps[landingUrl].clicked); - do_check_true(DirectoryLinksProvider._frequencyCaps["http://bar.com"].clicked); - - testObserver = new UrlDeletionTester(); - DirectoryLinksProvider.addObserver(testObserver); - yield PlacesTestUtils.clearHistory(); - - yield testObserver.promise; - DirectoryLinksProvider.removeObserver(testObserver); - // no clicks should remain in the cap object - do_check_false(DirectoryLinksProvider._frequencyCaps[landingUrl].hasOwnProperty("clicked")); - do_check_false(DirectoryLinksProvider._frequencyCaps["http://bar.com"].hasOwnProperty("clicked")); - - // verify that disk written data is kosher - data = yield readJsonFile(DirectoryLinksProvider._frequencyCapFilePath); - do_check_false(data[landingUrl].hasOwnProperty("clicked")); - do_check_false(data["http://bar.com"].hasOwnProperty("clicked")); - - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function test_DirectoryLinksProvider_anonymous() { - do_check_true(DirectoryLinksProvider._newXHR().mozAnon); -}); - -add_task(function* test_sanitizeExplanation() { - // Note: this is a basic test to ensure we applied sanitization to the link explanation. - // Full testing for appropriate sanitization is done in parser/xml/test/unit/test_sanitizer.js. - let data = {"suggested": [suggestedTile5]}; - let dataURI = 'data:application/json,' + encodeURIComponent(JSON.stringify(data)); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - yield fetchData(); - - let suggestedSites = [...DirectoryLinksProvider._suggestedLinks.keys()]; - do_check_eq(suggestedSites.indexOf("eviltarget.com"), 0); - do_check_eq(suggestedSites.length, 1); - - let suggestedLink = [...DirectoryLinksProvider._suggestedLinks.get(suggestedSites[0]).values()][0]; - do_check_eq(suggestedLink.explanation, "This is an evil tile X muhahaha"); - do_check_eq(suggestedLink.targetedName, "WE ARE EVIL "); -}); - -add_task(function* test_inadjecentSites() { - let suggestedTile = Object.assign({ - check_inadjacency: true - }, suggestedTile1); - - // Initial setup - let topSites = ["1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"]; - let data = {"suggested": [suggestedTile], "directory": [someOtherSite]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - - let testObserver = new TestFirstRun(); - DirectoryLinksProvider.addObserver(testObserver); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - let links = yield fetchData(); - - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = function(site) { - return topSites.indexOf(site) >= 0; - } - - let origGetProviderLinks = NewTabUtils.getProviderLinks; - NewTabUtils.getProviderLinks = function(provider) { - return links; - } - - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => { - origCurrentTopSiteCount.apply(DirectoryLinksProvider); - return 8; - }; - - // store oroginal inadjacent sites url - let origInadjacentSitesUrl = DirectoryLinksProvider._inadjacentSitesUrl; - - // loading inadjacent sites list function - function setInadjacentSites(sites) { - let badSiteB64 = []; - sites.forEach(site => { - badSiteB64.push(DirectoryLinksProvider._generateHash(site)); - }); - let theList = {"domains": badSiteB64}; - let uri = 'data:application/json,' + JSON.stringify(theList); - DirectoryLinksProvider._inadjacentSitesUrl = uri; - return DirectoryLinksProvider._loadInadjacentSites(); - } - - // setup gLinks loader - let gLinks = NewTabUtils.links; - gLinks.addProvider(DirectoryLinksProvider); - - function updateNewTabCache() { - gLinks.populateCache(); - return new Promise(resolve => { - NewTabUtils.allPages.register({ - observe: _ => _, - update() { - NewTabUtils.allPages.unregister(this); - resolve(); - } - }); - }); - } - - // no suggested file - do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined); - // _avoidInadjacentSites should be set, since link.check_inadjacency is on - do_check_true(DirectoryLinksProvider._avoidInadjacentSites); - // make sure example.com is included in inadjacent sites list - do_check_true(DirectoryLinksProvider._isInadjacentLink({baseDomain: "example.com"})); - - function TestFirstRun() { - this.promise = new Promise(resolve => { - this.onLinkChanged = (directoryLinksProvider, link) => { - do_check_eq(link.url, suggestedTile.url); - do_check_eq(link.type, "affiliate"); - resolve(); - }; - }); - } - - // Test first call to '_updateSuggestedTile()', called when fetching directory links. - yield testObserver.promise; - DirectoryLinksProvider.removeObserver(testObserver); - - // update newtab cache - yield updateNewTabCache(); - // this should have set - do_check_true(DirectoryLinksProvider._avoidInadjacentSites); - - // there should be siggested link - let link = DirectoryLinksProvider._updateSuggestedTile(); - do_check_eq(link.url, "http://turbotax.com"); - // and it should have avoidInadjacentSites flag - do_check_true(link.check_inadjacency); - - // make someothersite.com inadjacent - yield setInadjacentSites(["someothersite.com"]); - - // there should be no suggested link - link = DirectoryLinksProvider._updateSuggestedTile(); - do_check_false(link); - do_check_true(DirectoryLinksProvider._newTabHasInadjacentSite); - - // _handleLinkChanged must return true on inadjacent site - do_check_true(DirectoryLinksProvider._handleLinkChanged({ - url: "http://someothersite.com", - type: "history", - })); - // _handleLinkChanged must return false on ok site - do_check_false(DirectoryLinksProvider._handleLinkChanged({ - url: "http://foobar.com", - type: "history", - })); - - // change inadjacent list to sites not on newtab page - yield setInadjacentSites(["foo.com", "bar.com"]); - - link = DirectoryLinksProvider._updateSuggestedTile(); - // we should now have a link - do_check_true(link); - do_check_eq(link.url, "http://turbotax.com"); - - // make newtab offending again - yield setInadjacentSites(["someothersite.com", "foo.com"]); - // there should be no suggested link - link = DirectoryLinksProvider._updateSuggestedTile(); - do_check_false(link); - do_check_true(DirectoryLinksProvider._newTabHasInadjacentSite); - - // remove avoidInadjacentSites flag from suggested tile and reload json - delete suggestedTile.check_inadjacency; - data = {"suggested": [suggestedTile], "directory": [someOtherSite]}; - dataURI = 'data:application/json,' + JSON.stringify(data); - yield promiseDirectoryDownloadOnPrefChange(kSourceUrlPref, dataURI); - yield fetchData(); - - // inadjacent checking should be disabled - do_check_false(DirectoryLinksProvider._avoidInadjacentSites); - link = DirectoryLinksProvider._updateSuggestedTile(); - do_check_true(link); - do_check_eq(link.url, "http://turbotax.com"); - do_check_false(DirectoryLinksProvider._newTabHasInadjacentSite); - - // _handleLinkChanged should return false now, even if newtab has bad site - do_check_false(DirectoryLinksProvider._handleLinkChanged({ - url: "http://someothersite.com", - type: "history", - })); - - // test _isInadjacentLink - do_check_true(DirectoryLinksProvider._isInadjacentLink({baseDomain: "someothersite.com"})); - do_check_false(DirectoryLinksProvider._isInadjacentLink({baseDomain: "bar.com"})); - do_check_true(DirectoryLinksProvider._isInadjacentLink({url: "http://www.someothersite.com"})); - do_check_false(DirectoryLinksProvider._isInadjacentLink({url: "http://www.bar.com"})); - // try to crash _isInadjacentLink - do_check_false(DirectoryLinksProvider._isInadjacentLink({baseDomain: ""})); - do_check_false(DirectoryLinksProvider._isInadjacentLink({url: ""})); - do_check_false(DirectoryLinksProvider._isInadjacentLink({url: "http://localhost:8081/"})); - do_check_false(DirectoryLinksProvider._isInadjacentLink({url: "abracodabra"})); - do_check_false(DirectoryLinksProvider._isInadjacentLink({})); - - // test _checkForInadjacentSites - do_check_true(DirectoryLinksProvider._checkForInadjacentSites()); - - // Cleanup - gLinks.removeProvider(DirectoryLinksProvider); - DirectoryLinksProvider._inadjacentSitesUrl = origInadjacentSitesUrl; - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - NewTabUtils.getProviderLinks = origGetProviderLinks; - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; - yield promiseCleanDirectoryLinksProvider(); -}); - -add_task(function* test_blockSuggestedTiles() { - // Initial setup - let topSites = ["site0.com", "1040.com", "site2.com", "hrblock.com", "site4.com", "freetaxusa.com", "site6.com"]; - let data = {"suggested": [suggestedTile1, suggestedTile2, suggestedTile3], "directory": [someOtherSite]}; - let dataURI = 'data:application/json,' + JSON.stringify(data); - - yield promiseSetupDirectoryLinksProvider({linksURL: dataURI}); - let links = yield fetchData(); - - let origIsTopPlacesSite = NewTabUtils.isTopPlacesSite; - NewTabUtils.isTopPlacesSite = function(site) { - return topSites.indexOf(site) >= 0; - } - - let origGetProviderLinks = NewTabUtils.getProviderLinks; - NewTabUtils.getProviderLinks = function(provider) { - return links; - } - - let origCurrentTopSiteCount = DirectoryLinksProvider._getCurrentTopSiteCount; - DirectoryLinksProvider._getCurrentTopSiteCount = () => 8; - - // load the links - yield new Promise(resolve => { - DirectoryLinksProvider.getLinks(resolve); - }); - - // ensure that tile is suggested - let suggestedLink = DirectoryLinksProvider._updateSuggestedTile(); - do_check_true(suggestedLink.frecent_sites); - - // block suggested tile in a regular way - DirectoryLinksProvider.reportSitesAction([{ - isPinned: function() { return false; }, - link: Object.assign({frecency: 1000}, suggestedLink) - }], "block", 0); - - // suggested tile still must be recommended - suggestedLink = DirectoryLinksProvider._updateSuggestedTile(); - do_check_true(suggestedLink.frecent_sites); - - // timestamp suggested_block in the frequency cap object - DirectoryLinksProvider.handleSuggestedTileBlock(); - // no more recommendations should be seen - do_check_eq(DirectoryLinksProvider._updateSuggestedTile(), undefined); - - // move lastUpdated for suggested tile into the past - DirectoryLinksProvider._frequencyCaps["ignore://suggested_block"].lastUpdated = Date.now() - 25*60*60*1000; - // ensure that suggested tile updates again - suggestedLink = DirectoryLinksProvider._updateSuggestedTile(); - do_check_true(suggestedLink.frecent_sites); - - // Cleanup - yield promiseCleanDirectoryLinksProvider(); - NewTabUtils.isTopPlacesSite = origIsTopPlacesSite; - NewTabUtils.getProviderLinks = origGetProviderLinks; - DirectoryLinksProvider._getCurrentTopSiteCount = origCurrentTopSiteCount; -}); diff --git a/browser/modules/test/xpcshell/test_LaterRun.js b/browser/modules/test/xpcshell/test_LaterRun.js deleted file mode 100644 index 7b45c7cd5..000000000 --- a/browser/modules/test/xpcshell/test_LaterRun.js +++ /dev/null @@ -1,138 +0,0 @@ -"use strict"; - -const kEnabledPref = "browser.laterrun.enabled"; -const kPagePrefRoot = "browser.laterrun.pages."; -const kSessionCountPref = "browser.laterrun.bookkeeping.sessionCount"; -const kProfileCreationTime = "browser.laterrun.bookkeeping.profileCreationTime"; - -Components.utils.import("resource://gre/modules/Services.jsm"); -Components.utils.import("resource:///modules/LaterRun.jsm"); - -Services.prefs.setBoolPref(kEnabledPref, true); -Components.utils.import("resource://testing-common/AppInfo.jsm"); -updateAppInfo(); - -add_task(function* test_page_applies() { - Services.prefs.setCharPref(kPagePrefRoot + "test_LaterRun_unittest.url", "https://www.mozilla.org/%VENDOR%/%NAME%/%ID%/%VERSION%/"); - Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumHoursSinceInstall", 10); - Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumSessionCount", 3); - - let pages = LaterRun.readPages(); - // We have to filter the pages because it's possible Firefox ships with other URLs - // that get included in this test. - pages = pages.filter(page => page.pref == kPagePrefRoot + "test_LaterRun_unittest."); - Assert.equal(pages.length, 1, "Got 1 page"); - let page = pages[0]; - Assert.equal(page.pref, kPagePrefRoot + "test_LaterRun_unittest.", "Should know its own pref"); - Assert.equal(page.minimumHoursSinceInstall, 10, "Needs to have 10 hours since install"); - Assert.equal(page.minimumSessionCount, 3, "Needs to have 3 sessions"); - Assert.equal(page.requireBoth, false, "Either requirement is enough"); - let expectedURL = "https://www.mozilla.org/" + - Services.appinfo.vendor + "/" + - Services.appinfo.name + "/" + - Services.appinfo.ID + "/" + - Services.appinfo.version + "/"; - Assert.equal(page.url, expectedURL, "URL is stored correctly"); - - Assert.ok(page.applies({hoursSinceInstall: 1, sessionCount: 3}), - "Applies when session count has been met."); - Assert.ok(page.applies({hoursSinceInstall: 1, sessionCount: 4}), - "Applies when session count has been exceeded."); - Assert.ok(page.applies({hoursSinceInstall: 10, sessionCount: 2}), - "Applies when total session time has been met."); - Assert.ok(page.applies({hoursSinceInstall: 20, sessionCount: 2}), - "Applies when total session time has been exceeded."); - Assert.ok(page.applies({hoursSinceInstall: 10, sessionCount: 3}), - "Applies when both time and session count have been met."); - Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 1}), - "Does not apply when neither time and session count have been met."); - - page.requireBoth = true; - - Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 3}), - "Does not apply when only session count has been met."); - Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 4}), - "Does not apply when only session count has been exceeded."); - Assert.ok(!page.applies({hoursSinceInstall: 10, sessionCount: 2}), - "Does not apply when only total session time has been met."); - Assert.ok(!page.applies({hoursSinceInstall: 20, sessionCount: 2}), - "Does not apply when only total session time has been exceeded."); - Assert.ok(page.applies({hoursSinceInstall: 10, sessionCount: 3}), - "Applies when both time and session count have been met."); - Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 1}), - "Does not apply when neither time and session count have been met."); - - // Check that pages that have run never apply: - Services.prefs.setBoolPref(kPagePrefRoot + "test_LaterRun_unittest.hasRun", true); - page.requireBoth = false; - - Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 3}), - "Does not apply when page has already run (sessionCount equal)."); - Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 4}), - "Does not apply when page has already run (sessionCount exceeding)."); - Assert.ok(!page.applies({hoursSinceInstall: 10, sessionCount: 2}), - "Does not apply when page has already run (hoursSinceInstall equal)."); - Assert.ok(!page.applies({hoursSinceInstall: 20, sessionCount: 2}), - "Does not apply when page has already run (hoursSinceInstall exceeding)."); - Assert.ok(!page.applies({hoursSinceInstall: 10, sessionCount: 3}), - "Does not apply when page has already run (both criteria equal)."); - Assert.ok(!page.applies({hoursSinceInstall: 1, sessionCount: 1}), - "Does not apply when page has already run (both criteria insufficient anyway)."); - - clearAllPagePrefs(); -}); - -add_task(function* test_get_URL() { - Services.prefs.setIntPref(kProfileCreationTime, Math.floor((Date.now() - 11 * 60 * 60 * 1000) / 1000)); - Services.prefs.setCharPref(kPagePrefRoot + "test_LaterRun_unittest.url", "https://www.mozilla.org/"); - Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumHoursSinceInstall", 10); - Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumSessionCount", 3); - let pages = LaterRun.readPages(); - // We have to filter the pages because it's possible Firefox ships with other URLs - // that get included in this test. - pages = pages.filter(page => page.pref == kPagePrefRoot + "test_LaterRun_unittest."); - Assert.equal(pages.length, 1, "Should only be 1 matching page"); - let page = pages[0]; - let url; - do { - url = LaterRun.getURL(); - // We have to loop because it's possible Firefox ships with other URLs that get triggered by - // this test. - } while (url && url != "https://www.mozilla.org/"); - Assert.equal(url, "https://www.mozilla.org/", "URL should be as expected when prefs are set."); - Assert.ok(Services.prefs.prefHasUserValue(kPagePrefRoot + "test_LaterRun_unittest.hasRun"), "Should have set pref"); - Assert.ok(Services.prefs.getBoolPref(kPagePrefRoot + "test_LaterRun_unittest.hasRun"), "Should have set pref to true"); - Assert.ok(page.hasRun, "Other page objects should know it has run, too."); - - clearAllPagePrefs(); -}); - -add_task(function* test_insecure_urls() { - Services.prefs.setCharPref(kPagePrefRoot + "test_LaterRun_unittest.url", "http://www.mozilla.org/"); - Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumHoursSinceInstall", 10); - Services.prefs.setIntPref(kPagePrefRoot + "test_LaterRun_unittest.minimumSessionCount", 3); - let pages = LaterRun.readPages(); - // We have to filter the pages because it's possible Firefox ships with other URLs - // that get triggered in this test. - pages = pages.filter(page => page.pref == kPagePrefRoot + "test_LaterRun_unittest."); - Assert.equal(pages.length, 0, "URL with non-https scheme should get ignored"); - clearAllPagePrefs(); -}); - -add_task(function* test_dynamic_pref_getter_setter() { - delete LaterRun._sessionCount; - Services.prefs.setIntPref(kSessionCountPref, 0); - Assert.equal(LaterRun.sessionCount, 0, "Should start at 0"); - - LaterRun.sessionCount++; - Assert.equal(LaterRun.sessionCount, 1, "Should increment."); - Assert.equal(Services.prefs.getIntPref(kSessionCountPref), 1, "Should update pref"); -}); - -function clearAllPagePrefs() { - let allChangedPrefs = Services.prefs.getChildList(kPagePrefRoot); - for (let pref of allChangedPrefs) { - Services.prefs.clearUserPref(pref); - } -} - diff --git a/browser/modules/test/xpcshell/test_SitePermissions.js b/browser/modules/test/xpcshell/test_SitePermissions.js deleted file mode 100644 index 808d96599..000000000 --- a/browser/modules/test/xpcshell/test_SitePermissions.js +++ /dev/null @@ -1,115 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ -"use strict"; - -Components.utils.import("resource:///modules/SitePermissions.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -add_task(function* testPermissionsListing() { - Assert.deepEqual(SitePermissions.listPermissions().sort(), - ["camera", "cookie", "desktop-notification", "geo", "image", - "indexedDB", "install", "microphone", "popup", "screen"], - "Correct list of all permissions"); -}); - -add_task(function* testGetAllByURI() { - // check that it returns an empty array on an invalid URI - // like a file URI, which doesn't support site permissions - let wrongURI = Services.io.newURI("file:///example.js", null, null) - Assert.deepEqual(SitePermissions.getAllByURI(wrongURI), []); - - let uri = Services.io.newURI("https://example.com", null, null) - Assert.deepEqual(SitePermissions.getAllByURI(uri), []); - - SitePermissions.set(uri, "camera", SitePermissions.ALLOW); - Assert.deepEqual(SitePermissions.getAllByURI(uri), [ - { id: "camera", state: SitePermissions.ALLOW } - ]); - - SitePermissions.set(uri, "microphone", SitePermissions.SESSION); - SitePermissions.set(uri, "desktop-notification", SitePermissions.BLOCK); - - Assert.deepEqual(SitePermissions.getAllByURI(uri), [ - { id: "camera", state: SitePermissions.ALLOW }, - { id: "microphone", state: SitePermissions.SESSION }, - { id: "desktop-notification", state: SitePermissions.BLOCK } - ]); - - SitePermissions.remove(uri, "microphone"); - Assert.deepEqual(SitePermissions.getAllByURI(uri), [ - { id: "camera", state: SitePermissions.ALLOW }, - { id: "desktop-notification", state: SitePermissions.BLOCK } - ]); - - SitePermissions.remove(uri, "camera"); - SitePermissions.remove(uri, "desktop-notification"); - Assert.deepEqual(SitePermissions.getAllByURI(uri), []); - - // XXX Bug 1303108 - Control Center should only show non-default permissions - SitePermissions.set(uri, "addon", SitePermissions.BLOCK); - Assert.deepEqual(SitePermissions.getAllByURI(uri), []); - SitePermissions.remove(uri, "addon"); -}); - -add_task(function* testGetPermissionDetailsByURI() { - // check that it returns an empty array on an invalid URI - // like a file URI, which doesn't support site permissions - let wrongURI = Services.io.newURI("file:///example.js", null, null) - Assert.deepEqual(SitePermissions.getPermissionDetailsByURI(wrongURI), []); - - let uri = Services.io.newURI("https://example.com", null, null) - - SitePermissions.set(uri, "camera", SitePermissions.ALLOW); - SitePermissions.set(uri, "cookie", SitePermissions.SESSION); - SitePermissions.set(uri, "popup", SitePermissions.BLOCK); - - let permissions = SitePermissions.getPermissionDetailsByURI(uri); - - let camera = permissions.find(({id}) => id === "camera"); - Assert.deepEqual(camera, { - id: "camera", - label: "Use the Camera", - state: SitePermissions.ALLOW, - availableStates: [ - { id: SitePermissions.UNKNOWN, label: "Always Ask" }, - { id: SitePermissions.ALLOW, label: "Allow" }, - { id: SitePermissions.BLOCK, label: "Block" }, - ] - }); - - // check that removed permissions (State.UNKNOWN) are skipped - SitePermissions.remove(uri, "camera"); - permissions = SitePermissions.getPermissionDetailsByURI(uri); - - camera = permissions.find(({id}) => id === "camera"); - Assert.equal(camera, undefined); - - // check that different available state values are represented - - let cookie = permissions.find(({id}) => id === "cookie"); - Assert.deepEqual(cookie, { - id: "cookie", - label: "Set Cookies", - state: SitePermissions.SESSION, - availableStates: [ - { id: SitePermissions.ALLOW, label: "Allow" }, - { id: SitePermissions.SESSION, label: "Allow for Session" }, - { id: SitePermissions.BLOCK, label: "Block" }, - ] - }); - - let popup = permissions.find(({id}) => id === "popup"); - Assert.deepEqual(popup, { - id: "popup", - label: "Open Pop-up Windows", - state: SitePermissions.BLOCK, - availableStates: [ - { id: SitePermissions.ALLOW, label: "Allow" }, - { id: SitePermissions.BLOCK, label: "Block" }, - ] - }); - - SitePermissions.remove(uri, "cookie"); - SitePermissions.remove(uri, "popup"); -}); diff --git a/browser/modules/test/xpcshell/xpcshell.ini b/browser/modules/test/xpcshell/xpcshell.ini deleted file mode 100644 index 28df9c4ed..000000000 --- a/browser/modules/test/xpcshell/xpcshell.ini +++ /dev/null @@ -1,11 +0,0 @@ -[DEFAULT] -head = -tail = -firefox-appdir = browser -skip-if = toolkit == 'android' - -[test_AttributionCode.js] -skip-if = os != 'win' -[test_DirectoryLinksProvider.js] -[test_SitePermissions.js] -[test_LaterRun.js] |