|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ |
|
3 */ |
|
4 |
|
5 // Tests that various operations with file pointers work and do not affect the |
|
6 // source files |
|
7 |
|
8 var addon1 = { |
|
9 id: "addon1@tests.mozilla.org", |
|
10 version: "1.0", |
|
11 name: "Test 1", |
|
12 targetApplications: [{ |
|
13 id: "xpcshell@tests.mozilla.org", |
|
14 minVersion: "1", |
|
15 maxVersion: "1" |
|
16 }] |
|
17 }; |
|
18 |
|
19 var addon1_2 = { |
|
20 id: "addon1@tests.mozilla.org", |
|
21 version: "2.0", |
|
22 name: "Test 1", |
|
23 targetApplications: [{ |
|
24 id: "xpcshell@tests.mozilla.org", |
|
25 minVersion: "1", |
|
26 maxVersion: "1" |
|
27 }] |
|
28 }; |
|
29 |
|
30 var addon2 = { |
|
31 id: "addon2@tests.mozilla.org", |
|
32 version: "1.0", |
|
33 name: "Test 2", |
|
34 targetApplications: [{ |
|
35 id: "xpcshell@tests.mozilla.org", |
|
36 minVersion: "1", |
|
37 maxVersion: "1" |
|
38 }] |
|
39 }; |
|
40 |
|
41 const profileDir = gProfD.clone(); |
|
42 profileDir.append("extensions"); |
|
43 profileDir.create(AM_Ci.nsIFile.DIRECTORY_TYPE, 0755); |
|
44 |
|
45 const sourceDir = gProfD.clone(); |
|
46 sourceDir.append("source"); |
|
47 |
|
48 Components.utils.import("resource://testing-common/httpd.js"); |
|
49 var testserver; |
|
50 |
|
51 function writePointer(aId, aName) { |
|
52 let file = profileDir.clone(); |
|
53 file.append(aName ? aName : aId); |
|
54 |
|
55 let target = sourceDir.clone(); |
|
56 target.append(do_get_expected_addon_name(aId)); |
|
57 |
|
58 var fos = AM_Cc["@mozilla.org/network/file-output-stream;1"]. |
|
59 createInstance(AM_Ci.nsIFileOutputStream); |
|
60 fos.init(file, |
|
61 FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE, |
|
62 FileUtils.PERMS_FILE, 0); |
|
63 fos.write(target.path, target.path.length); |
|
64 fos.close(); |
|
65 } |
|
66 |
|
67 function writeRelativePointer(aId, aName) { |
|
68 let file = profileDir.clone(); |
|
69 file.append(aName ? aName : aId); |
|
70 |
|
71 let absTarget = sourceDir.clone(); |
|
72 absTarget.append(do_get_expected_addon_name(aId)); |
|
73 |
|
74 var relTarget = absTarget.getRelativeDescriptor(profileDir); |
|
75 |
|
76 var fos = AM_Cc["@mozilla.org/network/file-output-stream;1"]. |
|
77 createInstance(AM_Ci.nsIFileOutputStream); |
|
78 fos.init(file, |
|
79 FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE, |
|
80 FileUtils.PERMS_FILE, 0); |
|
81 fos.write(relTarget, relTarget.length); |
|
82 fos.close(); |
|
83 } |
|
84 |
|
85 function run_test() { |
|
86 // pointer files only work with unpacked directories |
|
87 if (Services.prefs.getBoolPref("extensions.alwaysUnpack") == false) |
|
88 return; |
|
89 |
|
90 do_test_pending(); |
|
91 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); |
|
92 |
|
93 // Create and configure the HTTP server. |
|
94 testserver = new HttpServer(); |
|
95 testserver.registerDirectory("/data/", do_get_file("data")); |
|
96 testserver.registerDirectory("/addons/", do_get_file("addons")); |
|
97 testserver.start(-1); |
|
98 gPort = testserver.identity.primaryPort; |
|
99 |
|
100 run_test_1(); |
|
101 } |
|
102 |
|
103 function end_test() { |
|
104 testserver.stop(do_test_finished); |
|
105 } |
|
106 |
|
107 // Tests that installing a new add-on by pointer works |
|
108 function run_test_1() { |
|
109 writeInstallRDFForExtension(addon1, sourceDir); |
|
110 writePointer(addon1.id); |
|
111 |
|
112 startupManager(); |
|
113 |
|
114 AddonManager.getAddonByID(addon1.id, function(a1) { |
|
115 do_check_neq(a1, null); |
|
116 do_check_eq(a1.version, "1.0"); |
|
117 |
|
118 let file = a1.getResourceURI().QueryInterface(AM_Ci.nsIFileURL).file; |
|
119 do_check_eq(file.parent.path, sourceDir.path); |
|
120 |
|
121 let rootUri = do_get_addon_root_uri(sourceDir, addon1.id); |
|
122 let uri = a1.getResourceURI("/"); |
|
123 do_check_eq(uri.spec, rootUri); |
|
124 uri = a1.getResourceURI("install.rdf"); |
|
125 do_check_eq(uri.spec, rootUri + "install.rdf"); |
|
126 |
|
127 // Check that upgrade is disabled for addons installed by file-pointers. |
|
128 do_check_eq(a1.permissions & AddonManager.PERM_CAN_UPGRADE, 0); |
|
129 run_test_2(); |
|
130 }); |
|
131 } |
|
132 |
|
133 // Tests that installing the addon from some other source doesn't clobber |
|
134 // the original sources |
|
135 function run_test_2() { |
|
136 prepare_test({}, [ |
|
137 "onNewInstall", |
|
138 ]); |
|
139 |
|
140 let url = "http://localhost:" + gPort + "/addons/test_filepointer.xpi"; |
|
141 AddonManager.getInstallForURL(url, function(install) { |
|
142 ensure_test_completed(); |
|
143 |
|
144 prepare_test({ |
|
145 "addon1@tests.mozilla.org": [ |
|
146 "onInstalling" |
|
147 ] |
|
148 }, [ |
|
149 "onDownloadStarted", |
|
150 "onDownloadEnded", |
|
151 "onInstallStarted", |
|
152 "onInstallEnded" |
|
153 ], callback_soon(check_test_2)); |
|
154 |
|
155 install.install(); |
|
156 }, "application/x-xpinstall"); |
|
157 } |
|
158 |
|
159 function check_test_2() { |
|
160 restartManager(); |
|
161 |
|
162 AddonManager.getAddonByID(addon1.id, function(a1) { |
|
163 do_check_neq(a1, null); |
|
164 do_check_eq(a1.version, "2.0"); |
|
165 |
|
166 let file = a1.getResourceURI().QueryInterface(AM_Ci.nsIFileURL).file; |
|
167 do_check_eq(file.parent.path, profileDir.path); |
|
168 |
|
169 let rootUri = do_get_addon_root_uri(profileDir, addon1.id); |
|
170 let uri = a1.getResourceURI("/"); |
|
171 do_check_eq(uri.spec, rootUri); |
|
172 uri = a1.getResourceURI("install.rdf"); |
|
173 do_check_eq(uri.spec, rootUri + "install.rdf"); |
|
174 |
|
175 let source = sourceDir.clone(); |
|
176 source.append(addon1.id); |
|
177 do_check_true(source.exists()); |
|
178 |
|
179 a1.uninstall(); |
|
180 |
|
181 do_execute_soon(run_test_3); |
|
182 }); |
|
183 } |
|
184 |
|
185 // Tests that uninstalling doesn't clobber the original sources |
|
186 function run_test_3() { |
|
187 restartManager(); |
|
188 |
|
189 writePointer(addon1.id); |
|
190 |
|
191 restartManager(); |
|
192 |
|
193 AddonManager.getAddonByID("addon1@tests.mozilla.org", callback_soon(function(a1) { |
|
194 do_check_neq(a1, null); |
|
195 do_check_eq(a1.version, "1.0"); |
|
196 |
|
197 a1.uninstall(); |
|
198 |
|
199 restartManager(); |
|
200 |
|
201 let source = sourceDir.clone(); |
|
202 source.append(addon1.id); |
|
203 do_check_true(source.exists()); |
|
204 |
|
205 do_execute_soon(run_test_4); |
|
206 })); |
|
207 } |
|
208 |
|
209 // Tests that misnaming a pointer doesn't clobber the sources |
|
210 function run_test_4() { |
|
211 writePointer("addon2@tests.mozilla.org", addon1.id); |
|
212 |
|
213 restartManager(); |
|
214 |
|
215 AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", |
|
216 "addon2@tests.mozilla.org"], function([a1, a2]) { |
|
217 do_check_eq(a1, null); |
|
218 do_check_eq(a2, null); |
|
219 |
|
220 let source = sourceDir.clone(); |
|
221 source.append(addon1.id); |
|
222 do_check_true(source.exists()); |
|
223 |
|
224 let pointer = profileDir.clone(); |
|
225 pointer.append("addon2@tests.mozilla.org"); |
|
226 do_check_false(pointer.exists()); |
|
227 |
|
228 do_execute_soon(run_test_5); |
|
229 }); |
|
230 } |
|
231 |
|
232 // Tests that changing the ID of an existing add-on doesn't clobber the sources |
|
233 function run_test_5() { |
|
234 var dest = writeInstallRDFForExtension(addon1, sourceDir); |
|
235 // Make sure the modification time changes enough to be detected. |
|
236 setExtensionModifiedTime(dest, dest.lastModifiedTime - 5000); |
|
237 writePointer(addon1.id); |
|
238 |
|
239 restartManager(); |
|
240 |
|
241 AddonManager.getAddonByID(addon1.id, callback_soon(function(a1) { |
|
242 do_check_neq(a1, null); |
|
243 do_check_eq(a1.version, "1.0"); |
|
244 |
|
245 writeInstallRDFForExtension(addon2, sourceDir, addon1.id); |
|
246 |
|
247 restartManager(); |
|
248 |
|
249 AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org", |
|
250 "addon2@tests.mozilla.org"], function([a1, a2]) { |
|
251 do_check_eq(a1, null); |
|
252 do_check_eq(a2, null); |
|
253 |
|
254 let source = sourceDir.clone(); |
|
255 source.append(addon1.id); |
|
256 do_check_true(source.exists()); |
|
257 |
|
258 let pointer = profileDir.clone(); |
|
259 pointer.append(addon1.id); |
|
260 do_check_false(pointer.exists()); |
|
261 |
|
262 do_execute_soon(run_test_6); |
|
263 }); |
|
264 })); |
|
265 } |
|
266 |
|
267 // Removing the pointer file should uninstall the add-on |
|
268 function run_test_6() { |
|
269 var dest = writeInstallRDFForExtension(addon1, sourceDir); |
|
270 // Make sure the modification time changes enough to be detected in run_test_8. |
|
271 setExtensionModifiedTime(dest, dest.lastModifiedTime - 5000); |
|
272 writePointer(addon1.id); |
|
273 |
|
274 restartManager(); |
|
275 |
|
276 AddonManager.getAddonByID(addon1.id, callback_soon(function(a1) { |
|
277 do_check_neq(a1, null); |
|
278 do_check_eq(a1.version, "1.0"); |
|
279 |
|
280 let pointer = profileDir.clone(); |
|
281 pointer.append(addon1.id); |
|
282 pointer.remove(false); |
|
283 |
|
284 restartManager(); |
|
285 |
|
286 AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) { |
|
287 do_check_eq(a1, null); |
|
288 |
|
289 do_execute_soon(run_test_7); |
|
290 }); |
|
291 })); |
|
292 } |
|
293 |
|
294 // Removing the pointer file and replacing it with a directory should work |
|
295 function run_test_7() { |
|
296 writePointer(addon1.id); |
|
297 |
|
298 restartManager(); |
|
299 |
|
300 AddonManager.getAddonByID("addon1@tests.mozilla.org", callback_soon(function(a1) { |
|
301 do_check_neq(a1, null); |
|
302 do_check_eq(a1.version, "1.0"); |
|
303 |
|
304 let pointer = profileDir.clone(); |
|
305 pointer.append(addon1.id); |
|
306 pointer.remove(false); |
|
307 |
|
308 writeInstallRDFForExtension(addon1_2, profileDir); |
|
309 |
|
310 restartManager(); |
|
311 |
|
312 AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) { |
|
313 do_check_neq(a1, null); |
|
314 do_check_eq(a1.version, "2.0"); |
|
315 |
|
316 a1.uninstall(); |
|
317 |
|
318 do_execute_soon(run_test_8); |
|
319 }); |
|
320 })); |
|
321 } |
|
322 |
|
323 // Changes to the source files should be detected |
|
324 function run_test_8() { |
|
325 restartManager(); |
|
326 |
|
327 writePointer(addon1.id); |
|
328 |
|
329 restartManager(); |
|
330 |
|
331 AddonManager.getAddonByID("addon1@tests.mozilla.org", callback_soon(function(a1) { |
|
332 do_check_neq(a1, null); |
|
333 do_check_eq(a1.version, "1.0"); |
|
334 |
|
335 writeInstallRDFForExtension(addon1_2, sourceDir); |
|
336 |
|
337 restartManager(); |
|
338 |
|
339 AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) { |
|
340 do_check_neq(a1, null); |
|
341 do_check_eq(a1.version, "2.0"); |
|
342 |
|
343 a1.uninstall(); |
|
344 |
|
345 do_execute_soon(run_test_9); |
|
346 }); |
|
347 })); |
|
348 } |
|
349 |
|
350 // Removing the add-on the pointer file points at should uninstall the add-on |
|
351 function run_test_9() { |
|
352 restartManager(); |
|
353 |
|
354 var dest = writeInstallRDFForExtension(addon1, sourceDir); |
|
355 writePointer(addon1.id); |
|
356 |
|
357 restartManager(); |
|
358 |
|
359 AddonManager.getAddonByID(addon1.id, callback_soon(function(a1) { |
|
360 do_check_neq(a1, null); |
|
361 do_check_eq(a1.version, "1.0"); |
|
362 |
|
363 dest.remove(true); |
|
364 |
|
365 restartManager(); |
|
366 |
|
367 AddonManager.getAddonByID(addon1.id, function(a1) { |
|
368 do_check_eq(a1, null); |
|
369 |
|
370 let pointer = profileDir.clone(); |
|
371 pointer.append(addon1.id); |
|
372 do_check_false(pointer.exists()); |
|
373 |
|
374 do_execute_soon(run_test_10); |
|
375 }); |
|
376 })); |
|
377 } |
|
378 |
|
379 // Tests that installing a new add-on by pointer with a relative path works |
|
380 function run_test_10() { |
|
381 writeInstallRDFForExtension(addon1, sourceDir); |
|
382 writeRelativePointer(addon1.id); |
|
383 |
|
384 restartManager(); |
|
385 |
|
386 AddonManager.getAddonByID(addon1.id, function(a1) { |
|
387 do_check_neq(a1, null); |
|
388 do_check_eq(a1.version, "1.0"); |
|
389 |
|
390 let file = a1.getResourceURI().QueryInterface(AM_Ci.nsIFileURL).file; |
|
391 do_check_eq(file.parent.path, sourceDir.path); |
|
392 |
|
393 let rootUri = do_get_addon_root_uri(sourceDir, addon1.id); |
|
394 let uri = a1.getResourceURI("/"); |
|
395 do_check_eq(uri.spec, rootUri); |
|
396 uri = a1.getResourceURI("install.rdf"); |
|
397 do_check_eq(uri.spec, rootUri + "install.rdf"); |
|
398 |
|
399 // Check that upgrade is disabled for addons installed by file-pointers. |
|
400 do_check_eq(a1.permissions & AddonManager.PERM_CAN_UPGRADE, 0); |
|
401 end_test(); |
|
402 }); |
|
403 } |