Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
1 <!DOCTYPE html>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id={821589}
5 -->
6 <head>
7 <title>Test for Bug {821589} Packaged apps installation and update</title>
8 <script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
9 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
11 </head>
12 <body>
14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={821589}">Mozilla Bug {821589}</a>
15 <p id="display"></p>
16 <div id="content" style="display: none">
18 </div>
19 <pre id="test">
20 <script class="testbody" type="application/javascript;version=1.8">
22 "use strict";
24 var index = -1;
26 function debug(aMsg) {
27 //dump("== Tests debug == " + aMsg + "\n");
28 }
30 function next() {
31 index += 1;
32 if (index >= steps.length) {
33 ok(false, "Shouldn't get here!");
34 return;
35 }
36 try {
37 steps[index]();
38 } catch(ex) {
39 ok(false, "Caught exception", ex);
40 }
41 }
43 function start() {
44 next();
45 }
47 function finish() {
48 SpecialPowers.removePermission("webapps-manage", document);
49 SimpleTest.finish();
50 }
52 function cbError(aError) {
53 ok(false, "Error callback invoked " + aError);
54 finish();
55 }
58 SimpleTest.waitForExplicitFinish();
60 var installTestApp, mm;
62 const PACKAGED_APP_ID = "test-app-id";
63 const PACKAGED_APP_ORIGIN = "app://" + PACKAGED_APP_ID;
64 const PACKAGED_APP_MANIFEST = PACKAGED_APP_ORIGIN + "/manifest.webapp";
65 const CERTIFIED_APP_ID = "test-certified-id";
66 const CERTIFIED_APP_ORIGIN = "app://" + CERTIFIED_APP_ID;
67 const CERTIFIED_APP_MANIFEST = CERTIFIED_APP_ORIGIN + "/manifest.webapp";
69 var steps = [
70 function() {
71 info("== SETUP ==");
72 // Set up
73 SpecialPowers.setAllAppsLaunchable(true);
74 SpecialPowers.addPermission("webapps-manage", true, document);
75 SpecialPowers.addPermission("browser", true, document);
76 SpecialPowers.addPermission("embed-apps", true, document);
78 // Required on firefox as these prefs are only set on b2g:
79 SpecialPowers.pushPrefEnv({
80 set: [["dom.mozBrowserFramesEnabled", true],
81 ["security.apps.privileged.CSP.default",
82 "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'"],
83 ["devtools.debugger.unix-domain-socket", 6000],
84 ["devtools.debugger.prompt-connection", false],
85 ["devtools.debugger.forbid-certified-apps", true]
86 ]
87 }, next);
88 },
89 function () {
90 // Load a chrome script in order to dispatch devtool debugger requests.
91 // Because of wrapping issues, we can't use SpecialPowers.Cu.import to load
92 // devtools jsm into mochitest scope. We end up not receiving
93 // DebuggerClient.addListener callback arguments...
94 let scriptUrl = SimpleTest.getTestFileURL("debugger-protocol-helper.js");
95 mm = SpecialPowers.loadChromeScript(scriptUrl);
96 installTestApp = function (url, appId, callback) {
97 let installResponse, appObject;
98 let installedEvent = false;
99 mm.addMessageListener("installed", function onInstalled(aResponse) {
100 mm.removeMessageListener("installed", onInstalled);
101 ok(true, "install request replied");
102 installResponse = aResponse;
103 checkEnd();
104 });
105 mm.addMessageListener("installed-event", function onInstalledEvent(aResponse) {
106 mm.removeMessageListener("installed-event", onInstalledEvent);
107 ok(true, "received appInstall actor event");
108 installedEvent = true;
109 checkEnd();
110 });
111 navigator.mozApps.mgmt.oninstall = function(evt) {
112 appObject = evt.application;
113 ok(true, "mozApps.mgmt install event fired");
114 checkEnd();
115 };
116 function checkEnd() {
117 if (appObject && installResponse && installedEvent)
118 callback(installResponse, appObject);
119 }
120 mm.sendAsyncMessage("install", {url: url, appId: appId});
121 };
122 SpecialPowers.autoConfirmAppInstall(next);
123 },
124 function() {
125 info("== TEST == Install packaged app");
126 let url = SimpleTest.getTestFileURL("data/app.zip");
127 installTestApp(url, PACKAGED_APP_ID,
128 function (aResponse, aApp) {
129 ok(true, "Installed");
130 is(aResponse.appId, PACKAGED_APP_ID, "Got same app id");
131 if ("error" in aResponse) {
132 ok(false, "Error: " + aResponse.error);
133 }
134 if ("message" in aResponse) {
135 ok(false, "Error message: " + aResponse.message);
136 }
137 ok(!("error" in aResponse), "app installed without any error");
138 is(aApp.manifest.name, "Test app", "app name is correct");
139 next();
140 }
141 );
142 },
143 function () {
144 info("== TEST == Reinstall packaged app");
145 let url = SimpleTest.getTestFileURL("data/app-updated.zip");
146 installTestApp(url, PACKAGED_APP_ID,
147 function (aResponse, aApp) {
148 ok(true, "Reinstalled");
149 is(aResponse.appId, PACKAGED_APP_ID, "Got same app id");
150 if ("error" in aResponse) {
151 ok(false, "Error: " + aResponse.error);
152 }
153 if ("message" in aResponse) {
154 ok(false, "Error message: " + aResponse.message);
155 }
156 ok(!("error" in aResponse), "app installed without any error");
157 is(aApp.manifest.name, "updated-name", "app name on update is correct");
158 next();
159 }
160 );
161 },
162 function() {
163 info("== TEST == Install certified app");
164 let url = SimpleTest.getTestFileURL("data/app-certified.zip");
165 installTestApp(url, CERTIFIED_APP_ID,
166 function (aResponse, aApp) {
167 ok(true, "Installed");
168 is(aResponse.appId, CERTIFIED_APP_ID, "Got same app id");
169 if ("error" in aResponse) {
170 ok(false, "Error: " + aResponse.error);
171 }
172 if ("message" in aResponse) {
173 ok(false, "Error message: " + aResponse.message);
174 }
175 ok(!("error" in aResponse), "app installed without any error");
176 is(aApp.manifest.name, "Certified app", "app name is correct");
177 next();
178 }
179 );
180 },
181 function() {
182 info("== TEST == Get all apps");
183 getAll(false);
184 },
185 function() {
186 info("== TEST == Get packaged app");
187 getApp({
188 id: PACKAGED_APP_ID,
189 manifestURL: PACKAGED_APP_MANIFEST
190 }, true);
191 },
192 function() {
193 info("== TEST == Get certified app");
194 getApp({
195 id: CERTIFIED_APP_ID,
196 manifestURL: CERTIFIED_APP_MANIFEST
197 }, false);
198 },
199 function() {
200 info("== SETUP == Enable certified app access");
201 SpecialPowers.pushPrefEnv({
202 "set": [["devtools.debugger.forbid-certified-apps", false]]
203 }, next);
204 },
205 function() {
206 info("== TEST == Get all apps (CERTIFIED ENABLED)");
207 getAll(true);
208 },
209 function() {
210 info("== TEST == Get packaged app (CERTIFIED ENABLED)");
211 getApp({
212 id: PACKAGED_APP_ID,
213 manifestURL: PACKAGED_APP_MANIFEST
214 }, true);
215 },
216 function() {
217 info("== TEST == Get certified app (CERTIFIED ENABLED)");
218 getApp({
219 id: CERTIFIED_APP_ID,
220 manifestURL: CERTIFIED_APP_MANIFEST
221 }, true);
222 },
223 function() {
224 info("== SETUP == Disable certified app access");
225 SpecialPowers.popPrefEnv(next);
226 },
227 function() {
228 info("== TEST == Uninstall packaged app");
229 uninstall(PACKAGED_APP_MANIFEST);
230 },
231 function() {
232 info("== TEST == Uninstall certified app");
233 uninstall(CERTIFIED_APP_MANIFEST);
234 },
235 function() {
236 ok(true, "all done!\n");
237 mm.sendAsyncMessage("cleanup");
238 SpecialPowers.flushPrefEnv(finish);
239 }
240 ];
242 addLoadEvent(start);
244 function getAll(expectCertified) {
245 mm.addMessageListener("appActorResponse", function onResponse(response) {
246 mm.removeMessageListener("appActorResponse", onResponse);
248 ok("apps" in response, "Apps found in getAll reply");
249 let apps = response.apps;
250 let packagedApp, certifiedApp;
251 for (let app of apps) {
252 switch (app.id) {
253 case PACKAGED_APP_ID:
254 packagedApp = app;
255 break;
256 case CERTIFIED_APP_ID:
257 certifiedApp = app;
258 break;
259 }
260 }
262 ok(packagedApp, "Packaged app found via getAll");
263 is(!!certifiedApp, expectCertified, "Certified app matches expectation");
265 next();
266 });
268 mm.sendAsyncMessage("appActorRequest", {
269 type: "getAll"
270 });
271 }
273 function getApp(appInfo, expected) {
274 mm.addMessageListener("appActorResponse", function onResponse(response) {
275 mm.removeMessageListener("appActorResponse", onResponse);
277 is("app" in response, expected, "App existence matches expectation");
278 is("error" in response, !expected, "Error existence matches expectation");
279 if (!expected) {
280 is(response.error, "forbidden", "Error message is correct");
281 next();
282 return;
283 }
285 let app = response.app;
286 for (let key in appInfo) {
287 is(app[key], appInfo[key], "Value for " + key + " matches");
288 }
290 next();
291 });
293 mm.sendAsyncMessage("appActorRequest", {
294 type: "getApp",
295 manifestURL: appInfo.manifestURL
296 });
297 }
299 function uninstall(manifestURL) {
300 mm.addMessageListener("appActorResponse", function onResponse(response) {
301 mm.removeMessageListener("appActorResponse", onResponse);
302 ok(!("error" in response), "App uninstalled successfully");
303 next();
304 });
306 mm.sendAsyncMessage("appActorRequest", {
307 type: "uninstall",
308 manifestURL: manifestURL
309 });
310 }
312 </script>
313 </pre>
314 </body>
315 </html>