gecko-dev/toolkit/devtools/apps/tests/test_webapps_actor.html

415 строки
13 KiB
HTML

<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id={821589}
-->
<head>
<title>Test for Bug {821589} Packaged apps installation and update</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={821589}">Mozilla Bug {821589}</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="application/javascript;version=1.8">
"use strict";
var index = -1;
function debug(aMsg) {
//dump("== Tests debug == " + aMsg + "\n");
}
function next() {
index += 1;
if (index >= steps.length) {
ok(false, "Shouldn't get here!");
return;
}
try {
steps[index]();
} catch(ex) {
ok(false, "Caught exception", ex);
}
}
function start() {
next();
}
function finish() {
SpecialPowers.removePermission("webapps-manage", document);
SimpleTest.finish();
}
function cbError(aError) {
ok(false, "Error callback invoked " + aError);
finish();
}
SimpleTest.waitForExplicitFinish();
var installTestApp, mm;
const PACKAGED_APP_ID = "test-app-id";
const PACKAGED_APP_ORIGIN = "app://" + PACKAGED_APP_ID;
const PACKAGED_APP_MANIFEST = PACKAGED_APP_ORIGIN + "/manifest.webapp";
const CERTIFIED_APP_ID = "test-certified-id";
const CERTIFIED_APP_ORIGIN = "app://" + CERTIFIED_APP_ID;
const CERTIFIED_APP_MANIFEST = CERTIFIED_APP_ORIGIN + "/manifest.webapp";
const SYSTEM_APP_ID = "test-system-id";
var steps = [
function() {
info("== SETUP ==");
// Set up
SpecialPowers.setAllAppsLaunchable(true);
SpecialPowers.addPermission("webapps-manage", true, document);
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.addPermission("embed-apps", true, document);
// Required on firefox as these prefs are only set on b2g:
SpecialPowers.pushPrefEnv({
set: [["dom.mozBrowserFramesEnabled", true],
["security.apps.privileged.CSP.default",
"default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'"],
["devtools.debugger.unix-domain-socket", 6000],
["devtools.debugger.prompt-connection", false],
["devtools.debugger.forbid-certified-apps", true]
]
}, next);
},
function () {
// Load a chrome script in order to dispatch devtool debugger requests.
// Because of wrapping issues, we can't use SpecialPowers.Cu.import to load
// devtools jsm into mochitest scope. We end up not receiving
// DebuggerClient.addListener callback arguments...
let scriptUrl = SimpleTest.getTestFileURL("debugger-protocol-helper.js");
mm = SpecialPowers.loadChromeScript(scriptUrl);
installTestApp = function (url, appId, callback) {
let installResponse, appObject;
let installedEvent = false;
function onInstalled(aResponse) {
ok(true, "install request replied");
installResponse = aResponse;
checkEnd();
}
mm.addMessageListener("installed", onInstalled);
function onInstalledEvent(aResponse) {
ok(true, "received appInstall actor event");
installedEvent = true;
checkEnd();
}
mm.addMessageListener("installed-event", onInstalledEvent);
navigator.mozApps.mgmt.oninstall = function(evt) {
appObject = evt.application;
ok(true, "mozApps.mgmt install event fired");
checkEnd();
};
function checkEnd() {
if ( (appObject && installResponse && installedEvent) ||
(installResponse && installResponse.error) ) {
mm.removeMessageListener("installed", onInstalled);
mm.removeMessageListener("installed-event", onInstalledEvent);
navigator.mozApps.mgmt.oninstall = null;
callback(installResponse, appObject);
}
}
mm.sendAsyncMessage("install", {url: url, appId: appId});
};
SpecialPowers.autoConfirmAppInstall(next);
},
function() {
info("== TEST == Install packaged app");
let url = SimpleTest.getTestFileURL("data/app.zip");
installTestApp(url, PACKAGED_APP_ID,
function (aResponse, aApp) {
ok(true, "Installed");
is(aResponse.appId, PACKAGED_APP_ID, "Got same app id");
if ("error" in aResponse) {
ok(false, "Error: " + aResponse.error);
}
if ("message" in aResponse) {
ok(false, "Error message: " + aResponse.message);
}
ok(!("error" in aResponse), "app installed without any error");
is(aApp.manifest.name, "Test app", "app name is correct");
next();
}
);
},
function () {
info("== TEST == Reinstall packaged app");
let url = SimpleTest.getTestFileURL("data/app-updated.zip");
installTestApp(url, PACKAGED_APP_ID,
function (aResponse, aApp) {
ok(true, "Reinstalled");
is(aResponse.appId, PACKAGED_APP_ID, "Got same app id");
if ("error" in aResponse) {
ok(false, "Error: " + aResponse.error);
}
if ("message" in aResponse) {
ok(false, "Error message: " + aResponse.message);
}
ok(!("error" in aResponse), "app installed without any error");
is(aApp.manifest.name, "updated-name", "app name on update is correct");
next();
}
);
},
function() {
info("== TEST == Install certified app");
let url = SimpleTest.getTestFileURL("data/app-certified.zip");
installTestApp(url, CERTIFIED_APP_ID,
function (aResponse, aApp) {
ok(true, "Installed");
is(aResponse.appId, CERTIFIED_APP_ID, "Got same app id");
if ("error" in aResponse) {
ok(false, "Error: " + aResponse.error);
}
if ("message" in aResponse) {
ok(false, "Error message: " + aResponse.message);
}
ok(!("error" in aResponse), "app installed without any error");
is(aApp.manifest.name, "Certified app", "app name is correct");
next();
}
);
},
function() {
info("== TEST == Try overloading non-removable app");
let url = SimpleTest.getTestFileURL("data/app-overload.zip");
installTestApp(url, CERTIFIED_APP_ID,
function (aResponse, aApp) {
// First time we install the app, it works just fine
ok(true, "Installed");
is(aResponse.appId, "overload.gaiamobile.org", "Got overloaded app id");
if ("error" in aResponse) {
ok(false, "Error: " + aResponse.error);
}
if ("message" in aResponse) {
ok(false, "Error message: " + aResponse.message);
}
ok(!("error" in aResponse), "app installed without any error");
is(aApp.manifest.name, "System app", "app name is correct");
// Then use some magic to make it non-removable
mm.sendAsyncMessage("tweak-app-object", {appId: CERTIFIED_APP_ID, removable: false});
// Then when trying to install it again, it will be rejected
installTestApp(url, CERTIFIED_APP_ID,
function (aResponse, aApp) {
is(aResponse.error, "installationFailed", "Overloading non-removable app without the pref is rejected");
is(aResponse.message, "The application " + CERTIFIED_APP_ID + " can't be overridden.");
next();
});
}
);
},
function() {
info("== TEST == Get all apps");
getAll(true);
},
function() {
info("== TEST == Get packaged app");
getApp({
id: PACKAGED_APP_ID,
manifestURL: PACKAGED_APP_MANIFEST
}, true);
},
function() {
info("== TEST == Get certified app");
getApp({
id: CERTIFIED_APP_ID,
manifestURL: CERTIFIED_APP_MANIFEST
}, true);
},
function() {
info("== SETUP == Enable certified app access");
SpecialPowers.pushPrefEnv({
"set": [["devtools.debugger.forbid-certified-apps", false]]
}, next);
},
function() {
info("== TEST == Get all apps (CERTIFIED ENABLED)");
getAll(true);
},
function() {
info("== TEST == Get packaged app (CERTIFIED ENABLED)");
getApp({
id: PACKAGED_APP_ID,
manifestURL: PACKAGED_APP_MANIFEST
}, true);
},
function() {
info("== TEST == Get certified app (CERTIFIED ENABLED)");
getApp({
id: CERTIFIED_APP_ID,
manifestURL: CERTIFIED_APP_MANIFEST
}, true);
},
function() {
info("== TEST == Overload of non-removable apps is allowed with CERTIFIED ENABLE");
let url = SimpleTest.getTestFileURL("data/app-overload.zip");
installTestApp(url, SYSTEM_APP_ID,
function (aResponse, aApp) {
ok(true, "Installed");
is(aResponse.appId, "overload.gaiamobile.org", "Got overloaded app id");
if ("error" in aResponse) {
ok(false, "Error: " + aResponse.error);
}
if ("message" in aResponse) {
ok(false, "Error message: " + aResponse.message);
}
ok(!("error" in aResponse), "app installed without any error");
is(aApp.manifest.name, "System app", "app name is correct");
next();
}
);
},
function() {
info("== SETUP == Disable certified app access");
SpecialPowers.popPrefEnv(next);
},
function() {
info("== TEST == Get packaged app actor");
addFrame(
{ mozapp: PACKAGED_APP_MANIFEST, remote: true },
function () {
getAppActor(PACKAGED_APP_MANIFEST, function (response) {
let tabActor = response.actor;
ok(!!tabActor, "TabActor is correctly instanciated in child.js");
ok("actor" in tabActor, "Tab actor is available in child");
ok("consoleActor" in tabActor, "Console actor is available in child");
next();
});
});
},
function() {
info("== TEST == Uninstall packaged app");
uninstall(PACKAGED_APP_MANIFEST);
},
function() {
info("== TEST == Uninstall certified app");
// Make the app removable again, but make it appear as a regular app (not being pushed via devtools)
mm.sendAsyncMessage("tweak-app-object", {appId: CERTIFIED_APP_ID, removable: true, sideloaded: false});
mm.addMessageListener("appActorResponse", function onResponse(response) {
mm.removeMessageListener("appActorResponse", onResponse);
is(response.error, "forbidden", "Uninstalling apps that have not being sideloaded is forbidden");
next();
});
mm.sendAsyncMessage("appActorRequest", {
type: "uninstall",
manifestURL: CERTIFIED_APP_MANIFEST
});
},
function() {
ok(true, "all done!\n");
mm.sendAsyncMessage("cleanup");
SpecialPowers.flushPrefEnv(finish);
}
];
addLoadEvent(start);
function getAll(expectCertified) {
mm.addMessageListener("appActorResponse", function onResponse(response) {
mm.removeMessageListener("appActorResponse", onResponse);
ok("apps" in response, "Apps found in getAll reply");
let apps = response.apps;
let packagedApp, certifiedApp;
for (let app of apps) {
switch (app.id) {
case PACKAGED_APP_ID:
packagedApp = app;
break;
case CERTIFIED_APP_ID:
certifiedApp = app;
break;
}
}
ok(packagedApp, "Packaged app found via getAll");
is(!!certifiedApp, expectCertified, "Certified app matches expectation");
next();
});
mm.sendAsyncMessage("appActorRequest", {
type: "getAll"
});
}
function getApp(appInfo, expected) {
mm.addMessageListener("appActorResponse", function onResponse(response) {
mm.removeMessageListener("appActorResponse", onResponse);
is("app" in response, expected, "App existence matches expectation");
is("error" in response, !expected, "Error existence matches expectation");
if (!expected) {
is(response.error, "forbidden", "Error message is correct");
next();
return;
}
let app = response.app;
for (let key in appInfo) {
is(app[key], appInfo[key], "Value for " + key + " matches");
}
next();
});
mm.sendAsyncMessage("appActorRequest", {
type: "getApp",
manifestURL: appInfo.manifestURL
});
}
function uninstall(manifestURL) {
mm.addMessageListener("appActorResponse", function onResponse(response) {
mm.removeMessageListener("appActorResponse", onResponse);
ok(!("error" in response), "App uninstalled successfully");
next();
});
mm.sendAsyncMessage("appActorRequest", {
type: "uninstall",
manifestURL: manifestURL
});
}
function getAppActor(manifestURL, callback) {
mm.addMessageListener("appActor", function onAppActor(aResponse) {
mm.removeMessageListener("appActor", onAppActor);
callback(aResponse);
});
mm.sendAsyncMessage("getAppActor", { manifestURL: manifestURL });
}
function addFrame(options, callback) {
mm.addMessageListener("frameAdded", function onFrameAdded() {
mm.removeMessageListener("frameAdded", onFrameAdded);
callback();
});
mm.sendAsyncMessage("addFrame", options);
}
</script>
</pre>
</body>
</html>