fune/toolkit/components/url-classifier/tests/browser/classifierTester.js
Kirk Steuber 68f7cb1b36 Bug 1350381 - Change Flash blocking to allow the setting "Ask to Activate" to control CTA of unknown documents. r=qdot
Previously, we operated under the understanding that with Flash blocking activated, non-whitelisted documents would be set to CTA. We are changing that such that now, documents will only be CTA'ed if Flash is set to "Ask to Activate".

Flash blocking will now behave according to the following chart:

User Setting   Flash block   Whitelisted sites   Blacklisted sites    Unlisted sites
"Never ..."    Off           Deny                Deny                 Deny
"Ask ..."      Off           Ask                 Ask                  Ask
"Always ..."   Off           Allow               Allow                Allow
"Never ..."    On            Deny                Deny                 Deny
"Ask ..."      On            Allow               Deny                 Ask
"Always ..."   On            Allow               Deny                 Allow

This patch also completely reworks the flash blocking testing. Test data and most code remains consolidated, but will be run in multiple different tests. This avoids having to extend the timeout for Flash block testing to an extremely long length. The new Flash block testing additionally tests each of the six cases (rows) in the table above.

MozReview-Commit-ID: 5aPGUEiUiCv

--HG--
extra : rebase_source : d5f5711855d108a9a33b9d28aae6e312cc9cb432
2017-03-24 14:15:02 -07:00

337 lines
12 KiB
JavaScript

/* 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/Task.jsm");
var classifierTester = {
URL_PATH: "/browser/toolkit/components/url-classifier/tests/browser/flash_block_frame.html",
OBJECT_ID: "testObject",
IFRAME_ID: "testFrame",
FLASHBLOCK_ENABLE_PREF: "plugins.flashBlock.enabled",
FLASH_PLUGIN_USER_SETTING_PREF: "plugin.state.flash",
NEVER_ACTIVATE_PREF_VALUE: 0,
ASK_TO_ACTIVATE_PREF_VALUE: 1,
ALWAYS_ACTIVATE_PREF_VALUE: 2,
ALLOW_CTA_PREF: "plugins.click_to_play",
dbUrls: [
{
url: "flashallow.example.com/",
db: "test-flashallow-simple",
pref: "urlclassifier.flashAllowTable"
},
{
url: "exception.flashallow.example.com/",
db: "testexcept-flashallow-simple",
pref: "urlclassifier.flashAllowExceptTable"
},
{
url: "flashblock.example.com/",
db: "test-flash-simple",
pref: "urlclassifier.flashTable"
},
{
url: "exception.flashblock.example.com/",
db: "testexcept-flash-simple",
pref: "urlclassifier.flashExceptTable"
},
{
url: "subdocument.example.com/",
db: "test-flashsubdoc-simple",
pref: "urlclassifier.flashThirdPartyTable"
},
{
url: "exception.subdocument.example.com/",
db: "testexcept-flashsubdoc-simple",
pref: "urlclassifier.flashThirdPartyExceptTable"
}
],
setPrefs: function ({setDBs = true, flashBlockEnable = true, flashSetting = classifierTester.ALWAYS_ACTIVATE_PREF_VALUE} = {}) {
if (setDBs) {
for (let dbData of classifierTester.dbUrls) {
Services.prefs.setCharPref(dbData.pref, dbData.db);
}
}
Services.prefs.setBoolPref(classifierTester.FLASHBLOCK_ENABLE_PREF,
flashBlockEnable);
Services.prefs.setIntPref(classifierTester.FLASH_PLUGIN_USER_SETTING_PREF,
flashSetting);
Services.prefs.setBoolPref(classifierTester.ALLOW_CTA_PREF, true);
},
unsetPrefs: function () {
for (let dbData of classifierTester.dbUrls) {
Services.prefs.clearUserPref(dbData.pref);
}
Services.prefs.clearUserPref(classifierTester.FLASHBLOCK_ENABLE_PREF);
Services.prefs.clearUserPref(classifierTester.FLASH_PLUGIN_USER_SETTING_PREF);
Services.prefs.clearUserPref(classifierTester.ALLOW_CTA_PREF);
},
// The |domains| property describes the domains of the nested documents making
// up the page. |domains[0]| represents the domain in the URL bar. The last
// domain in the list is the domain of the most deeply nested iframe.
// Only the plugin in the most deeply nested document will be checked.
testCases: [
{
name: "Unknown domain",
domains: ["http://example.com"],
expectedFlashClassification: "unknown"
},
{
name: "Nested unknown domains",
domains: ["http://example.com", "http://example.org"],
expectedFlashClassification: "unknown"
},
{
name: "Allowed domain",
domains: ["http://flashallow.example.com"],
expectedFlashClassification: "allowed"
},
{
name: "Allowed nested domain",
domains: ["http://example.com", "http://flashallow.example.com"],
expectedFlashClassification: "allowed"
},
{
name: "Subdocument of allowed domain",
domains: ["http://flashallow.example.com", "http://example.com"],
expectedFlashClassification: "allowed"
},
{
name: "Exception to allowed domain",
domains: ["http://exception.flashallow.example.com"],
expectedFlashClassification: "unknown"
},
{
name: "Blocked domain",
domains: ["http://flashblock.example.com"],
expectedFlashClassification: "denied"
},
{
name: "Nested blocked domain",
domains: ["http://example.com", "http://flashblock.example.com"],
expectedFlashClassification: "denied"
},
{
name: "Subdocument of blocked subdocument",
domains: ["http://example.com", "http://flashblock.example.com", "http://example.com"],
expectedFlashClassification: "denied"
},
{
name: "Blocked subdocument nested among in allowed documents",
domains: ["http://flashallow.example.com", "http://flashblock.example.com", "http://flashallow.example.com"],
expectedFlashClassification: "denied"
},
{
name: "Exception to blocked domain",
domains: ["http://exception.flashblock.example.com"],
expectedFlashClassification: "unknown"
},
{
name: "Sub-document blocked domain in top-level context",
domains: ["http://subdocument.example.com"],
expectedFlashClassification: "unknown"
},
{
name: "Sub-document blocked domain",
domains: ["http://example.com", "http://subdocument.example.com"],
expectedFlashClassification: "denied"
},
{
name: "Sub-document blocked domain in non-Third-Party context",
domains: ["http://subdocument.example.com", "http://subdocument.example.com"],
expectedFlashClassification: "unknown"
},
{
name: "Sub-document blocked domain differing only by scheme",
domains: ["http://subdocument.example.com", "https://subdocument.example.com"],
expectedFlashClassification: "denied"
},
{
name: "Sub-document blocked subdocument of an allowed domain",
domains: ["http://flashallow.example.com", "http://subdocument.example.com"],
expectedFlashClassification: "denied"
},
{
name: "Subdocument of Sub-document blocked domain",
domains: ["http://example.com", "http://subdocument.example.com", "http://example.com"],
expectedFlashClassification: "denied"
},
{
name: "Sub-document exception in top-level context",
domains: ["http://exception.subdocument.example.com"],
expectedFlashClassification: "unknown"
},
{
name: "Sub-document blocked domain exception",
domains: ["http://example.com", "http://exception.subdocument.example.com"],
expectedFlashClassification: "unknown"
}
],
// Returns null if this value should not be verified given the combination
// of inputs
expectedPluginFallbackType: function (classification, flashSetting) {
switch(classification) {
case "unknown":
if (flashSetting == classifierTester.ALWAYS_ACTIVATE_PREF_VALUE) {
return null;
} else if (flashSetting == classifierTester.ASK_TO_ACTIVATE_PREF_VALUE) {
return Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY;
} else if (flashSetting == classifierTester.NEVER_ACTIVATE_PREF_VALUE) {
return Ci.nsIObjectLoadingContent.PLUGIN_DISABLED;
}
break;
case "allowed":
if (flashSetting == classifierTester.NEVER_ACTIVATE_PREF_VALUE) {
return Ci.nsIObjectLoadingContent.PLUGIN_DISABLED;
}
return null;
case "denied":
return Ci.nsIObjectLoadingContent.PLUGIN_USER_DISABLED;
}
throw new Error("Invalid classification or flash setting");
},
// Returns null if this value should not be verified given the combination
// of inputs
expectedActivated: function (classification, flashSetting) {
switch(classification) {
case "unknown":
return (flashSetting == classifierTester.ALWAYS_ACTIVATE_PREF_VALUE);
case "allowed":
return (flashSetting != classifierTester.NEVER_ACTIVATE_PREF_VALUE);
case "denied":
return false;
}
throw new Error("Invalid classification or flash setting");
},
// Returns null if this value should not be verified given the combination
// of inputs
expectedHasRunningPlugin: function (classification, flashSetting) {
switch(classification) {
case "unknown":
return (flashSetting == classifierTester.ALWAYS_ACTIVATE_PREF_VALUE);
case "allowed":
return (flashSetting != classifierTester.NEVER_ACTIVATE_PREF_VALUE);
case "denied":
return false;
}
throw new Error("Invalid classification or flash setting");
},
// Returns null if this value should not be verified given the combination
// of inputs
expectedPluginListed: function (classification, flashSetting) {
if (flashSetting == classifierTester.ASK_TO_ACTIVATE_PREF_VALUE &&
Services.prefs.getCharPref('plugins.navigator.hidden_ctp_plugin') == "Shockwave Flash") {
return false;
}
switch(classification) {
case "unknown":
case "allowed":
return (flashSetting != classifierTester.NEVER_ACTIVATE_PREF_VALUE);
case "denied":
return false;
}
throw new Error("Invalid classification or flash setting");
},
buildTestCaseInNewTab: function (browser, testCase) {
return Task.spawn(function* () {
let iframeDomains = testCase.domains.slice();
let pageDomain = iframeDomains.shift();
let tab = yield BrowserTestUtils.openNewForegroundTab(browser,
pageDomain + classifierTester.URL_PATH);
let depth = 0;
for (let domain of iframeDomains) {
// Firefox does not like to load the same page in its own iframe. Put some
// bogus query strings in the URL to make it happy.
let url = domain + classifierTester.URL_PATH + "?date=" + Date.now() + "rand=" + Math.random();
let domainLoaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, true, url);
ContentTask.spawn(tab.linkedBrowser, {iframeId: classifierTester.IFRAME_ID, url: url, depth: depth},
function*({iframeId, url, depth}) {
let doc = content.document;
for (let i = 0; i < depth; ++i) {
doc = doc.getElementById(iframeId).contentDocument;
}
doc.getElementById(iframeId).src = url;
});
yield domainLoaded;
++depth;
}
return tab;
});
},
getPluginInfo: function (browser, depth) {
return ContentTask.spawn(browser,
{iframeId: classifierTester.IFRAME_ID, depth: depth},
function* ({iframeId, depth}) {
let doc = content.document;
let win = content.window;
for (let i = 0; i < depth; ++i) {
let frame = doc.getElementById(iframeId);
doc = frame.contentDocument;
win = frame.contentWindow;
}
let pluginObj = doc.getElementById("testObject");
if (!(pluginObj instanceof Ci.nsIObjectLoadingContent)) {
throw new Error("Unable to find plugin!");
}
return {
pluginFallbackType: pluginObj.pluginFallbackType,
activated: pluginObj.activated,
hasRunningPlugin: pluginObj.hasRunningPlugin,
listed: ("Shockwave Flash" in win.navigator.plugins),
flashClassification: doc.documentFlashClassification
};
});
},
checkPluginInfo: function (pluginInfo, expectedClassification, flashSetting) {
is(pluginInfo.flashClassification, expectedClassification,
"Page's classification should match expected");
let expectedPluginFallbackType =
classifierTester.expectedPluginFallbackType(pluginInfo.flashClassification,
flashSetting);
if (expectedPluginFallbackType != null) {
is(pluginInfo.pluginFallbackType, expectedPluginFallbackType,
"Plugin should have the correct fallback type");
}
let expectedActivated =
classifierTester.expectedActivated(pluginInfo.flashClassification,
flashSetting);
if (expectedActivated != null) {
is(pluginInfo.activated, expectedActivated,
"Plugin should have the correct activation");
}
let expectedHasRunningPlugin =
classifierTester.expectedHasRunningPlugin(pluginInfo.flashClassification,
flashSetting);
if (expectedHasRunningPlugin != null) {
is(pluginInfo.hasRunningPlugin, expectedHasRunningPlugin,
"Plugin should have the correct 'plugin running' state");
}
let expectedPluginListed =
classifierTester.expectedPluginListed(pluginInfo.flashClassification,
flashSetting);
if (expectedPluginListed != null) {
is(pluginInfo.listed, expectedPluginListed,
"Plugin's existance in navigator.plugins should match expected");
}
}
};
registerCleanupFunction(classifierTester.unsetPrefs);