|
1 "use strict"; |
|
2 |
|
3 const Cu = Components.utils; |
|
4 const Cc = Components.classes; |
|
5 const Ci = Components.interfaces; |
|
6 |
|
7 Cu.import("resource://gre/modules/OperatorApps.jsm"); |
|
8 Cu.import("resource://gre/modules/FileUtils.jsm"); |
|
9 Cu.import("resource://gre/modules/NetUtil.jsm"); |
|
10 |
|
11 // From prio.h |
|
12 const PR_RDWR = 0x04; |
|
13 const PR_CREATE_FILE = 0x08; |
|
14 const PR_TRUNCATE = 0x20; |
|
15 |
|
16 SimpleTest.waitForExplicitFinish(); |
|
17 |
|
18 var gApp = null; |
|
19 |
|
20 var index = -1; |
|
21 var singlevariantDir = undefined; |
|
22 |
|
23 function debug(aMsg) { |
|
24 //dump("== Tests debug == " + aMsg + "\n"); |
|
25 } |
|
26 |
|
27 |
|
28 var updateData = { |
|
29 name : "testOperatorApp1", |
|
30 version : 2, |
|
31 size : 767, |
|
32 package_path: "http://test/tests/dom/apps/tests/file_packaged_app.sjs", |
|
33 description: "Updated even faster than Firefox, just to annoy slashdotters", |
|
34 developer: { |
|
35 name: "Tester Operator App", |
|
36 url: "http://mochi.test:8888" |
|
37 } |
|
38 }; |
|
39 |
|
40 var manifestData = { |
|
41 name : "testOperatorApp1", |
|
42 version : 2, |
|
43 description: "Updated even faster than Firefox, just to annoy slashdotters", |
|
44 launch_path: "index.html", |
|
45 developer: { |
|
46 name: "Tester Operator App", |
|
47 url: "http://mochi.test:8888" |
|
48 }, |
|
49 default_locale: "en-US" |
|
50 }; |
|
51 |
|
52 var metadataData = { |
|
53 id: "testOperatorApp1", |
|
54 installOrigin: "http://mochi.test:8888", |
|
55 manifestURL: "http://test/tests/dom/apps/tests/file_packaged_app.sjs", |
|
56 origin: "http://test" |
|
57 }; |
|
58 |
|
59 function writeFile(aFile, aData, aCb) { |
|
60 debug("Saving " + aFile.path); |
|
61 // Initialize the file output stream. |
|
62 let ostream = FileUtils.openSafeFileOutputStream(aFile); |
|
63 |
|
64 // Obtain a converter to convert our data to a UTF-8 encoded input stream. |
|
65 let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] |
|
66 .createInstance(Ci.nsIScriptableUnicodeConverter); |
|
67 converter.charset = "UTF-8"; |
|
68 |
|
69 // Asynchronously copy the data to the file. |
|
70 let istream = converter.convertToInputStream(aData); |
|
71 NetUtil.asyncCopy(istream, ostream, function(rc) { |
|
72 FileUtils.closeSafeFileOutputStream(ostream); |
|
73 if (aCb) |
|
74 aCb(); |
|
75 }); |
|
76 } |
|
77 |
|
78 // File and resources helpers |
|
79 function addZipEntry(zipWriter, entry, entryName) { |
|
80 var stream = Cc["@mozilla.org/io/string-input-stream;1"] |
|
81 .createInstance(Ci.nsIStringInputStream); |
|
82 stream.setData(entry, entry.length); |
|
83 zipWriter.addEntryStream(entryName, Date.now(), |
|
84 Ci.nsIZipWriter.COMPRESSION_BEST, stream, false); |
|
85 } |
|
86 |
|
87 function setupDataDirs(aCb) { |
|
88 let dirNum = "tmp_" + Math.floor(Math.random() * 10000000 + 1); |
|
89 let tmpDir = FileUtils.getDir("TmpD", [dirNum, "singlevariantapps"], true, |
|
90 true); |
|
91 let appDir = FileUtils.getDir("TmpD", [dirNum, "singlevariantapps", |
|
92 "testOperatorApp1"], true, true); |
|
93 |
|
94 singlevariantDir = tmpDir.path; |
|
95 let singlevariantFile = tmpDir.clone(); |
|
96 singlevariantFile.append("singlevariantconf.json"); |
|
97 |
|
98 |
|
99 writeFile(singlevariantFile, JSON.stringify({"214-007":["testOperatorApp1"]}), |
|
100 function() { |
|
101 let indexhtml = "<html></html>"; |
|
102 let manifest = JSON.stringify(manifestData); |
|
103 // Create the application package. |
|
104 var zipWriter = Cc["@mozilla.org/zipwriter;1"] |
|
105 .createInstance(Ci.nsIZipWriter); |
|
106 var zipFile = FileUtils.getFile("TmpD", [ |
|
107 dirNum, |
|
108 "singlevariantapps", |
|
109 "testOperatorApp1", |
|
110 "application.zip"]); |
|
111 zipWriter.open(zipFile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); |
|
112 addZipEntry(zipWriter, indexhtml, "index.html"); |
|
113 addZipEntry(zipWriter, manifest, "manifest.webapp"); |
|
114 zipWriter.close(); |
|
115 |
|
116 var metadataFile = appDir.clone(); |
|
117 metadataFile.append("metadata.json"); |
|
118 writeFile(metadataFile, JSON.stringify(metadataData), function() { |
|
119 var updateFile = appDir.clone(); |
|
120 updateFile.append("update.webapp"); |
|
121 writeFile(updateFile, JSON.stringify(updateData), aCb); |
|
122 }); |
|
123 }); |
|
124 } |
|
125 |
|
126 function next() { |
|
127 index += 1; |
|
128 if (index >= steps.length) { |
|
129 ok(false, "Shouldn't get here!"); |
|
130 return; |
|
131 } |
|
132 try { |
|
133 steps[index](); |
|
134 } catch(ex) { |
|
135 ok(false, "Caught exception", ex); |
|
136 } |
|
137 } |
|
138 |
|
139 function go() { |
|
140 next(); |
|
141 } |
|
142 |
|
143 function finish() { |
|
144 SimpleTest.finish(); |
|
145 } |
|
146 |
|
147 function mozAppsError() { |
|
148 ok(false, "mozApps error: " + this.error.name); |
|
149 finish(); |
|
150 } |
|
151 |
|
152 function installOperatorApp(aMcc, aMnc) { |
|
153 OperatorAppsRegistry.appsDir = singlevariantDir; |
|
154 OperatorAppsRegistry._installOperatorApps(aMcc, aMnc); |
|
155 } |
|
156 |
|
157 function checkAppState(aApp, |
|
158 aVersion, |
|
159 aExpectedApp, |
|
160 aCb) { |
|
161 debug(JSON.stringify(aApp, null, 2)); |
|
162 if (aApp.manifest) { |
|
163 debug(JSON.stringify(aApp.manifest, null, 2)); |
|
164 } |
|
165 |
|
166 if (aExpectedApp.name) { |
|
167 if (aApp.manifest) { |
|
168 is(aApp.manifest.name, aExpectedApp.name, "Check name"); |
|
169 } |
|
170 is(aApp.updateManifest.name, aExpectedApp.name, "Check name mini-manifest"); |
|
171 } |
|
172 if (aApp.manifest) { |
|
173 is(aApp.manifest.version, aVersion, "Check version"); |
|
174 } |
|
175 if (typeof aExpectedApp.size !== "undefined" && aApp.manifest) { |
|
176 is(aApp.manifest.size, aExpectedApp.size, "Check size"); |
|
177 } |
|
178 if (aApp.manifest) { |
|
179 is(aApp.manifest.launch_path, "index.html", "Check launch path"); |
|
180 } |
|
181 if (aExpectedApp.manifestURL) { |
|
182 is(aApp.manifestURL, aExpectedApp.manifestURL, "Check manifestURL"); |
|
183 } |
|
184 if (aExpectedApp.installOrigin) { |
|
185 is(aApp.installOrigin, aExpectedApp.installOrigin, "Check installOrigin"); |
|
186 } |
|
187 ok(aApp.removable, "Removable app"); |
|
188 if (typeof aExpectedApp.progress !== "undefined") { |
|
189 todo(aApp.progress == aExpectedApp.progress, "Check progress"); |
|
190 } |
|
191 if (aExpectedApp.installState) { |
|
192 is(aApp.installState, aExpectedApp.installState, "Check installState"); |
|
193 } |
|
194 if (typeof aExpectedApp.downloadAvailable !== "undefined") { |
|
195 is(aApp.downloadAvailable, aExpectedApp.downloadAvailable, |
|
196 "Check download available"); |
|
197 } |
|
198 if (typeof aExpectedApp.downloading !== "undefined") { |
|
199 is(aApp.downloading, aExpectedApp.downloading, "Check downloading"); |
|
200 } |
|
201 if (typeof aExpectedApp.downloadSize !== "undefined") { |
|
202 is(aApp.downloadSize, aExpectedApp.downloadSize, "Check downloadSize"); |
|
203 } |
|
204 if (typeof aExpectedApp.readyToApplyDownload !== "undefined") { |
|
205 is(aApp.readyToApplyDownload, aExpectedApp.readyToApplyDownload, |
|
206 "Check readyToApplyDownload"); |
|
207 } |
|
208 if (aCb && typeof aCb === 'function') { |
|
209 aCb(); |
|
210 } |
|
211 return; |
|
212 } |
|
213 |
|
214 var steps = [ |
|
215 function() { |
|
216 setupDataDirs(next); |
|
217 ok(true, "Data directory set up to " + singlevariantDir); |
|
218 }, |
|
219 function() { |
|
220 ok(true, "autoConfirmAppInstall"); |
|
221 SpecialPowers.autoConfirmAppInstall(next); |
|
222 }, |
|
223 function() { |
|
224 ok(true, "== TEST == Install operator app"); |
|
225 |
|
226 navigator.mozApps.mgmt.oninstall = function(evt) { |
|
227 ok(true, "Got oninstall event"); |
|
228 gApp = evt.application; |
|
229 gApp.ondownloaderror = function() { |
|
230 ok(false, "Download error " + gApp.downloadError.name); |
|
231 finish(); |
|
232 }; |
|
233 let downloadsuccessHandler = function() { |
|
234 gApp.ondownloadsuccess = null; |
|
235 ok(true, "App downloaded"); |
|
236 |
|
237 var expected = { |
|
238 name: manifestData.name, |
|
239 manifestURL: metadataData.manifestURL, |
|
240 installOrigin: metadataData.installOrigin, |
|
241 progress: 0, |
|
242 installState: "installed", |
|
243 downloadAvailable: false, |
|
244 downloading: false, |
|
245 downloadSize: 767, |
|
246 readyToApplyDownload: false |
|
247 }; |
|
248 checkAppState(gApp, manifestData.version, expected, next); |
|
249 }; |
|
250 gApp.ondownloadsuccess = downloadsuccessHandler; |
|
251 if (!gApp.downloading && gApp.ondownloadsuccess) { |
|
252 ok(true, "Got an earlier event"); |
|
253 // Seems we set the handler too late. |
|
254 gApp.ondownloadsuccess = null; |
|
255 downloadsuccessHandler(); |
|
256 } |
|
257 }; |
|
258 installOperatorApp("214", "007"); |
|
259 }, |
|
260 function() { |
|
261 ok(true, "all done!\n"); |
|
262 finish(); |
|
263 } |
|
264 ]; |
|
265 |
|
266 go(); |
|
267 |