Bug 873403 - Convert test_bug260264.html to use SpecialPowers. r=jst

This commit is contained in:
Martijn Wargers 2013-09-20 12:50:26 +02:00
parent 87f458cb95
commit 8c7db7907e
4 changed files with 240 additions and 291 deletions

View File

@ -1,14 +1,11 @@
<html>
<head>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript" src="utils_bug260264.js"></script>
</head>
<body>
<iframe id="frame"></iframe>
<script type="application/javascript">
document.getElementById("frame").src =
alter_file(alter_host(location.href, "mochi.test:8888"),
"grandchild_bug260264.html");
var tempstr = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')+1);
document.getElementById("frame").src = "http://mochi.test:8888" + tempstr + "grandchild_bug260264.html" + window.location.hash;
</script>
</body>
</html>

View File

@ -25,117 +25,157 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=260264
SimpleTest.waitForExplicitFinish();
/**
* These functions can be called without arguments to retrieve the current
* value of the preference/privilege, or called with a single argument to set
* the preference/privilege to a new value.
*
* In other words, they obey the interface that |hold| expects its |accessor|
* parameter to obey.
*/
var popupMax = makePrefAccessor("dom.popup_maximum"),
popupEvents = makePrefAccessor("dom.popup_allowed_events"),
blockPopups = makePrefAccessor("dom.disable_open_during_load"),
ownPopupPriv = makePopupPrivAccessor(location.href);
var a = $("link"),
checkOpened = function() { ok(window.open("http://example.com"), "not properly opened") },
checkBlocked = function() { ok(!window.open("http://example.com"), "not properly blocked") };
/**
* Intentional popups are not limited by dom.popup_maximum.
*/
function testIntentional(event) {
hold(popupMax, 3, function() {
send(a, event, checkOpened);
send(a, event, checkOpened);
send(a, event, checkOpened);
send(a, event, checkOpened);
});
window.open.close();
}
/**
* Probably-intentional popups are limited only by dom.popup_maximum, and
* closing the popup window immediately allows another to open.
*/
function testProbablyIntentional(event) {
var max = 3;
hold(popupMax, max, function() {
for (var count = 0, n = 0; n < max; n++)
send(a, event, function() { if (window.open("http://example.com")) count++ });
send(a, event, checkBlocked);
window.open.close(1);
send(a, event, checkOpened);
send(a, event, checkBlocked);
send(a, event, checkBlocked);
window.open.close();
ok(count > 0, "Windows left open by previous tests?");
while (count --> 0)
send(a, event, checkOpened);
send(a, event, checkBlocked);
});
window.open.close();
}
/**
* Probably-unintentional popups are forbidden entirely.
*/
function testProbablyUnintentional(event) {
hold(popupMax, 2, function() {
send(a, event, checkBlocked);
});
window.open.close();
}
/**
* Please be patient; run_tests opens/closes a LOT of windows.
*/
function run_tests() {
hold(popupEvents, "click mouseup", function() {
// Note: UNKNOWN_ACTION is the same as DENY_ACTION.
hold(ownPopupPriv, DENY_ACTION, function() {
testIntentional("click");
testProbablyIntentional("mouseup");
testProbablyUnintentional("mouseover");
});
hold(ownPopupPriv, ALLOW_ACTION, function() {
testIntentional("click");
testIntentional("mouseup");
testProbablyIntentional("mouseover");
});
});
send(a, "click", checkOpened);
send(a, "click", checkOpened);
send(a, "click", checkOpened);
send(a, "click", checkOpened);
window.open.close();
hold(popupEvents, "click", function() {
// Note: UNKNOWN_ACTION is the same as DENY_ACTION.
hold(ownPopupPriv, DENY_ACTION, function() {
testIntentional("click");
testProbablyUnintentional("mouseup");
testProbablyUnintentional("mouseover");
});
hold(ownPopupPriv, ALLOW_ACTION, function() {
testIntentional("click");
testProbablyIntentional("mouseup");
testProbablyIntentional("mouseover");
});
});
SpecialPowers.pushPrefEnv({"set": [["dom.popup_maximum", 3]]}, run_tests2);
}
window.open.close(); // just in case
function run_tests2() {
for (var count = 0, n = 0; n < 3; n++)
send(a, "mouseup", function() { if (window.open("http://example.com")) count++ });
send(a, "mouseup", checkBlocked);
window.open.close(1);
send(a, "mouseup", checkOpened);
send(a, "mouseup", checkBlocked);
send(a, "mouseup", checkBlocked);
window.open.close();
ok(count > 0, "Windows left open by previous tests?");
while (count --> 0)
send(a, "mouseup", checkOpened);
send(a, "mouseup", checkBlocked);
window.open.close();
SpecialPowers.pushPrefEnv({"set": [["dom.popup_maximum", 2]]}, run_tests3);
}
function run_tests3() {
send(a, "mouseover", checkBlocked);
window.open.close();
SpecialPowers.pushPermissions([{'type': 'popup', 'allow': ALLOW_ACTION, 'context': document}], function() {
SpecialPowers.pushPrefEnv({"set": [["dom.popup_maximum", 3]]}, run_tests4);
});
}
function run_tests4() {
send(a, "click", checkOpened);
send(a, "click", checkOpened);
send(a, "click", checkOpened);
send(a, "click", checkOpened);
window.open.close();
send(a, "mouseup", checkOpened);
send(a, "mouseup", checkOpened);
send(a, "mouseup", checkOpened);
send(a, "mouseup", checkOpened);
window.open.close();
for (var count = 0, n = 0; n < 3; n++)
send(a, "mouseover", function() { if (window.open("http://example.com")) count++ });
send(a, "mouseover", checkBlocked);
window.open.close(1);
send(a, "mouseover", checkOpened);
send(a, "mouseover", checkBlocked);
send(a, "mouseover", checkBlocked);
window.open.close();
ok(count > 0, "Windows left open by previous tests?");
while (count --> 0)
send(a, "mouseover", checkOpened);
send(a, "mouseover", checkBlocked);
window.open.close();
SpecialPowers.pushPrefEnv({"set": [["dom.popup_allowed_events", "click"]]}, run_tests5);
}
function run_tests5() {
SpecialPowers.pushPermissions([{'type': 'popup', 'allow': DENY_ACTION, 'context': document}], run_tests6);
}
function run_tests6() {
send(a, "click", checkOpened);
send(a, "click", checkOpened);
send(a, "click", checkOpened);
send(a, "click", checkOpened);
window.open.close();
SpecialPowers.pushPrefEnv({"set": [["dom.popup_maximum", 2]]}, run_tests7);
}
function run_tests7() {
send(a, "mouseup", checkBlocked);
window.open.close();
send(a, "mouseover", checkBlocked);
window.open.close();
SpecialPowers.pushPermissions([{'type': 'popup', 'allow': ALLOW_ACTION, 'context': document}], function() {
SpecialPowers.pushPrefEnv({"set": [["dom.popup_maximum", 3]]}, run_tests8);
});
}
function run_tests8() {
send(a, "click", checkOpened);
send(a, "click", checkOpened);
send(a, "click", checkOpened);
send(a, "click", checkOpened);
window.open.close();
for (var count = 0, n = 0; n < 3; n++)
send(a, "mouseup", function() { if (window.open("http://example.com")) count++ });
send(a, "mouseup", checkBlocked);
window.open.close(1);
send(a, "mouseup", checkOpened);
send(a, "mouseup", checkBlocked);
send(a, "mouseup", checkBlocked);
window.open.close();
ok(count > 0, "Windows left open by previous tests?");
while (count --> 0)
send(a, "mouseup", checkOpened);
send(a, "mouseup", checkBlocked);
window.open.close();
for (var count = 0, n = 0; n < 3; n++)
send(a, "mouseover", function() { if (window.open("http://example.com")) count++ });
send(a, "mouseover", checkBlocked);
window.open.close(1);
send(a, "mouseover", checkOpened);
send(a, "mouseover", checkBlocked);
send(a, "mouseover", checkBlocked);
window.open.close();
ok(count > 0, "Windows left open by previous tests?");
while (count --> 0)
send(a, "mouseover", checkOpened);
send(a, "mouseover", checkBlocked);
window.open.close();
SimpleTest.finish();
}
function check_sanity() {
hold(ownPopupPriv, UNKNOWN_ACTION, function(unknown) {
hold(ownPopupPriv, ALLOW_ACTION, function(allow) {
is(ownPopupPriv(), allow, "properly set to allow");
});
is(ownPopupPriv(), unknown, "properly reset to unknown");
ok(SpecialPowers.testPermission('popup', UNKNOWN_ACTION, document), 'popup value should have UNKNOWN permission');
SpecialPowers.pushPermissions([{'type': 'popup', 'allow': true, 'context': document}], check_sanity2);
}
function check_sanity2() {
ok(SpecialPowers.testPermission('popup', ALLOW_ACTION, document), 'popup value should have ALLOW permission');
SpecialPowers.pushPrefEnv({"set": [["dom.disable_open_during_load", true],
["dom.popup_allowed_events", "click mouseup"],
["dom.popup_maximum", 3]]}, function() {
// Note: UNKNOWN_ACTION is the same as DENY_ACTION.
SpecialPowers.pushPermissions([{'type': 'popup', 'allow': DENY_ACTION, 'context': document}], run_tests);
});
}
setTimeout(function() {
check_sanity();
hold(blockPopups, true, run_tests);
SimpleTest.finish();
SpecialPowers.pushPermissions([{'type': 'popup', 'remove': true, 'context': document}], check_sanity);
}, 200);
</script>

View File

@ -22,96 +22,112 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=260264
SimpleTest.waitForExplicitFinish();
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var popupEvents = makePrefAccessor("dom.popup_allowed_events"),
blockPopups = makePrefAccessor("dom.disable_open_during_load"),
ownPopupPriv = makePopupPrivAccessor(location.href),
ecPopupPriv = makePopupPrivAccessor("http://example.com");
function makeIframe(aEvent) {
var tempURL = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')+1);
tempURL = 'http://example.com' + tempURL + "child_bug260264.html#" + aEvent;
$("display").appendChild(document.createElement("iframe")).src = tempURL;
}
function test_nested_frames() {
SpecialPowers.pushPrefEnv({"set": [["dom.disable_open_during_load", true]]}, test_nested_frames2);
}
var savedBlockPopups = blockPopups(true);
function test_nested_frames2() {
// Grandchild will use this name to refer to the current window:
window.name = "parent260264";
function performer(event) {
$("display").appendChild(document.createElement("iframe")).src =
alter_file(alter_host(location.href, "example.com"),
"child_bug260264.html#" + event);
if (tests[0]) {
tests[0].setup(function() {makeIframe(tests[0].event);});
} else {
ok(false, "There should have run 8 tests here");
SimpleTest.finish();
}
}
function finisher(old) {
popupEvents(old.events);
ownPopupPriv(old.ownPriv);
ecPopupPriv(old.ecPriv);
function should_have_blocked(popup) {
ok(!popup, "popup should have been blocked");
}
function should_not_have_blocked(popup) {
ok(popup, "popup should not have been blocked");
}
function setupPP(aAllowedEvents, aPopup1, aPopup2, aNext) {
SpecialPowers.pushPrefEnv({"set": [["dom.popup_allowed_events", aAllowedEvents]]}, function() {
SpecialPowers.pushPermissions([{'type': 'popup', 'allow': aPopup1, 'context': document},
{'type': 'popup', 'allow': aPopup2, 'context': 'http://example.com'}], aNext);
});
}
/**
* The example_priv (DENY_ACTION) parameter controls whether or not the child frame has
* popup clearance. Neither the top window nor the grandchild frame have
* this clearance. The point of these tests is to make sure the child's
* clearance (or lack thereof) is properly considered when opening a popup
* from the grandchild.
*/
var tests = [
{ event: "mouseup",
setup: function(aNext) {
setupPP("click mouseup", DENY_ACTION, DENY_ACTION, aNext);
},
report: should_not_have_blocked
},
{ event: "mouseup",
setup: function(aNext) {
setupPP("click mouseup", ALLOW_ACTION, ALLOW_ACTION, aNext);
},
report: should_not_have_blocked
},
{ event: "mouseup",
setup: function(aNext) {
setupPP("click", ALLOW_ACTION, ALLOW_ACTION, aNext);
},
report: should_not_have_blocked
},
{ event: "mouseup",
setup: function(aNext) {
setupPP("click", DENY_ACTION, DENY_ACTION, aNext);
},
report: should_have_blocked
},
{ event: "mouseover",
setup: function(aNext) {
setupPP("click mouseup", DENY_ACTION, DENY_ACTION, aNext);
},
report: should_have_blocked
},
{ event: "mouseover",
setup: function(aNext) {
setupPP("click mouseup", ALLOW_ACTION, ALLOW_ACTION, aNext);
},
report: should_not_have_blocked
},
{ event: "click",
setup: function(aNext) {
setupPP("click mouseup", DENY_ACTION, DENY_ACTION, aNext);
},
report: should_not_have_blocked
},
{ event: "click",
setup: function(aNext) {
setupPP("click mouseup", ALLOW_ACTION, ALLOW_ACTION, aNext);
},
report: should_not_have_blocked
}
];
// Visible to child windows:
function report(popup) {
tests[0].report(popup);
tests.shift();
if (tests[0]) {
tests[0].setup(function() {makeIframe(tests[0].event);});
} else {
SimpleTest.finish();
}
function should_have_blocked(popup) {
ok(!popup, "popup should have been blocked");
}
function should_not_have_blocked(popup) {
ok(popup, "popup should not have been blocked");
}
/**
* The example_priv parameter controls whether or not the child frame has
* popup clearance. Neither the top window nor the grandchild frame have
* this clearance. The point of these tests is to make sure the child's
* clearance (or lack thereof) is properly considered when opening a popup
* from the grandchild.
*/
function makeTest(event, example_priv, reporter, allowed_events) {
return {
event: event,
setup: function(old) {
old.events = popupEvents(allowed_events || "click mouseup");
old.ownPriv = ownPopupPriv(DENY_ACTION);
old.ecPriv = ecPopupPriv(example_priv);
},
report: reporter,
perform: performer,
finish: finisher
};
};
var tests = [
makeTest("mouseup", DENY_ACTION, should_not_have_blocked),
makeTest("mouseup", ALLOW_ACTION, should_not_have_blocked),
makeTest("mouseup", ALLOW_ACTION, should_not_have_blocked, "click"),
makeTest("mouseup", DENY_ACTION, should_have_blocked, "click"),
makeTest("mouseover", DENY_ACTION, should_have_blocked),
makeTest("mouseover", ALLOW_ACTION, should_not_have_blocked),
makeTest("click", DENY_ACTION, should_not_have_blocked),
makeTest("click", ALLOW_ACTION, should_not_have_blocked)
];
function resume() {
var options = tests[0];
if (options) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
options.setup(tests[0].old = {});
options.perform(options.event);
} else {
blockPopups(savedBlockPopups);
SimpleTest.finish();
}
}
// Visible to child windows:
window.report = function(popup) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
try { tests[0].report(popup) }
finally {
tests[0].finish(tests[0].old);
tests.shift();
resume();
}
}
resume();
}
test_nested_frames();

View File

@ -1,3 +1,8 @@
const ALLOW_ACTION = SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION;
const DENY_ACTION = SpecialPowers.Ci.nsIPermissionManager.DENY_ACTION;
const UNKNOWN_ACTION = SpecialPowers.Ci.nsIPermissionManager.UNKNOWN_ACTION;
const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION;
/**
* Dispatches |handler| to |element|, as if fired in response to |event|.
*/
@ -29,112 +34,3 @@ function send(element, event, handler) {
}
};
})(window.open);
function _alter_helper(uri, fn) {
var hash_splat = uri.split("#"),
splat = hash_splat.shift().split("/");
fn(splat);
hash_splat.unshift(splat.join("/"));
return hash_splat.join("#");
}
function alter_host(uri, host) {
return _alter_helper(uri, function(splat) {
splat.splice(2, 1, host);
});
}
function alter_file(uri, file) {
return _alter_helper(uri, function(splat) {
splat[splat.length - 1] = file;
});
}
(function() {
var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
.getService(SpecialPowers.Ci.nsIPrefService),
pm = SpecialPowers.Cc["@mozilla.org/permissionmanager;1"]
.getService(SpecialPowers.Ci.nsIPermissionManager),
ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]
.getService(SpecialPowers.Ci.nsIIOService);
ALLOW_ACTION = pm.ALLOW_ACTION;
DENY_ACTION = pm.DENY_ACTION;
UNKNOWN_ACTION = pm.UNKNOWN_ACTION;
/**
* This ridiculously over-engineered function makes an accessor function from
* any given preference string. Such accessors may be passed as the first
* parameter to the |hold| function defined below.
*/
makePrefAccessor = function(pref) {
var splat = pref.split('.'),
basePref = splat.pop(),
branch, kind;
try {
branch = prefService.getBranch(splat.join('.') + '.');
} catch (x) {
alert("Calling prefService.getBranch failed: " +
"did you forget to enable UniversalXPConnect?");
throw x;
}
switch (branch.getPrefType(basePref)) {
case branch.PREF_STRING: kind = "CharPref"; break;
case branch.PREF_INT: kind = "IntPref"; break;
case branch.PREF_BOOL: kind = "BoolPref"; break;
case branch.PREF_INVALID: kind = "ComplexValue";
}
return function(value) {
var oldValue = branch['get' + kind](basePref);
if (arguments.length > 0)
branch['set' + kind](basePref, value);
return oldValue;
};
};
makePopupPrivAccessor = function(uri) {
uri = ioService.newURI(uri, null, null);
var principal = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(SpecialPowers.Ci.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
return function(permission) {
var old = pm.testPermissionFromPrincipal(principal, "popup");
if (arguments.length) {
pm.removeFromPrincipal(principal, "popup");
pm.addFromPrincipal(principal, "popup", permission);
}
return old;
};
};
})();
/**
* This function takes an accessor function, a new value, and a callback
* function. It assigns the new value to the accessor, saving the old value,
* then calls the callback function with the new and old values. Before
* returning, |hold| sets the accessor back to the old value, even if the
* callback function misbehaved (i.e., threw).
*
* For sanity's sake, |hold| also ensures that the accessor still has the new
* value at the time the old value is reassigned. The accessor's value might
* have changed to something entirely different during the execution of the
* callback function, but it must have changed back.
*
* Without such a mechanism it would be very difficult to verify that these
* tests leave the browser's preferences/privileges as they were originally.
*/
function hold(accessor, value, body) {
var old_value = accessor(value);
try { return body(value, old_value) }
finally {
old_value = accessor(old_value);
if (old_value !== value)
throw [accessor, value, old_value];
}
}