зеркало из https://github.com/mozilla/gecko-dev.git
415 строки
13 KiB
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>
|