|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
|
4 */ |
|
5 const URI_EXTENSION_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"; |
|
6 |
|
7 const Ci = Components.interfaces; |
|
8 const Cu = Components.utils; |
|
9 |
|
10 Cu.import("resource://testing-common/httpd.js"); |
|
11 |
|
12 var ADDONS = [{ |
|
13 id: "test_bug449027_1@tests.mozilla.org", |
|
14 name: "Bug 449027 Addon Test 1", |
|
15 version: "5", |
|
16 start: false, |
|
17 appBlocks: false, |
|
18 toolkitBlocks: false |
|
19 }, { |
|
20 id: "test_bug449027_2@tests.mozilla.org", |
|
21 name: "Bug 449027 Addon Test 2", |
|
22 version: "5", |
|
23 start: false, |
|
24 appBlocks: true, |
|
25 toolkitBlocks: false |
|
26 }, { |
|
27 id: "test_bug449027_3@tests.mozilla.org", |
|
28 name: "Bug 449027 Addon Test 3", |
|
29 version: "5", |
|
30 start: false, |
|
31 appBlocks: true, |
|
32 toolkitBlocks: false |
|
33 }, { |
|
34 id: "test_bug449027_4@tests.mozilla.org", |
|
35 name: "Bug 449027 Addon Test 4", |
|
36 version: "5", |
|
37 start: false, |
|
38 appBlocks: false, |
|
39 toolkitBlocks: false |
|
40 }, { |
|
41 id: "test_bug449027_5@tests.mozilla.org", |
|
42 name: "Bug 449027 Addon Test 5", |
|
43 version: "5", |
|
44 start: false, |
|
45 appBlocks: false, |
|
46 toolkitBlocks: false |
|
47 }, { |
|
48 id: "test_bug449027_6@tests.mozilla.org", |
|
49 name: "Bug 449027 Addon Test 6", |
|
50 version: "5", |
|
51 start: false, |
|
52 appBlocks: true, |
|
53 toolkitBlocks: false |
|
54 }, { |
|
55 id: "test_bug449027_7@tests.mozilla.org", |
|
56 name: "Bug 449027 Addon Test 7", |
|
57 version: "5", |
|
58 start: false, |
|
59 appBlocks: true, |
|
60 toolkitBlocks: false |
|
61 }, { |
|
62 id: "test_bug449027_8@tests.mozilla.org", |
|
63 name: "Bug 449027 Addon Test 8", |
|
64 version: "5", |
|
65 start: false, |
|
66 appBlocks: true, |
|
67 toolkitBlocks: false |
|
68 }, { |
|
69 id: "test_bug449027_9@tests.mozilla.org", |
|
70 name: "Bug 449027 Addon Test 9", |
|
71 version: "5", |
|
72 start: false, |
|
73 appBlocks: true, |
|
74 toolkitBlocks: false |
|
75 }, { |
|
76 id: "test_bug449027_10@tests.mozilla.org", |
|
77 name: "Bug 449027 Addon Test 10", |
|
78 version: "5", |
|
79 start: false, |
|
80 appBlocks: true, |
|
81 toolkitBlocks: false |
|
82 }, { |
|
83 id: "test_bug449027_11@tests.mozilla.org", |
|
84 name: "Bug 449027 Addon Test 11", |
|
85 version: "5", |
|
86 start: false, |
|
87 appBlocks: true, |
|
88 toolkitBlocks: false |
|
89 }, { |
|
90 id: "test_bug449027_12@tests.mozilla.org", |
|
91 name: "Bug 449027 Addon Test 12", |
|
92 version: "5", |
|
93 start: false, |
|
94 appBlocks: true, |
|
95 toolkitBlocks: false |
|
96 }, { |
|
97 id: "test_bug449027_13@tests.mozilla.org", |
|
98 name: "Bug 449027 Addon Test 13", |
|
99 version: "5", |
|
100 start: false, |
|
101 appBlocks: true, |
|
102 toolkitBlocks: false |
|
103 }, { |
|
104 id: "test_bug449027_14@tests.mozilla.org", |
|
105 name: "Bug 449027 Addon Test 14", |
|
106 version: "5", |
|
107 start: false, |
|
108 appBlocks: false, |
|
109 toolkitBlocks: false |
|
110 }, { |
|
111 id: "test_bug449027_15@tests.mozilla.org", |
|
112 name: "Bug 449027 Addon Test 15", |
|
113 version: "5", |
|
114 start: false, |
|
115 appBlocks: true, |
|
116 toolkitBlocks: true |
|
117 }, { |
|
118 id: "test_bug449027_16@tests.mozilla.org", |
|
119 name: "Bug 449027 Addon Test 16", |
|
120 version: "5", |
|
121 start: false, |
|
122 appBlocks: true, |
|
123 toolkitBlocks: true |
|
124 }, { |
|
125 id: "test_bug449027_17@tests.mozilla.org", |
|
126 name: "Bug 449027 Addon Test 17", |
|
127 version: "5", |
|
128 start: false, |
|
129 appBlocks: false, |
|
130 toolkitBlocks: false |
|
131 }, { |
|
132 id: "test_bug449027_18@tests.mozilla.org", |
|
133 name: "Bug 449027 Addon Test 18", |
|
134 version: "5", |
|
135 start: false, |
|
136 appBlocks: false, |
|
137 toolkitBlocks: false |
|
138 }, { |
|
139 id: "test_bug449027_19@tests.mozilla.org", |
|
140 name: "Bug 449027 Addon Test 19", |
|
141 version: "5", |
|
142 start: false, |
|
143 appBlocks: true, |
|
144 toolkitBlocks: true |
|
145 }, { |
|
146 id: "test_bug449027_20@tests.mozilla.org", |
|
147 name: "Bug 449027 Addon Test 20", |
|
148 version: "5", |
|
149 start: false, |
|
150 appBlocks: true, |
|
151 toolkitBlocks: true |
|
152 }, { |
|
153 id: "test_bug449027_21@tests.mozilla.org", |
|
154 name: "Bug 449027 Addon Test 21", |
|
155 version: "5", |
|
156 start: false, |
|
157 appBlocks: true, |
|
158 toolkitBlocks: true |
|
159 }, { |
|
160 id: "test_bug449027_22@tests.mozilla.org", |
|
161 name: "Bug 449027 Addon Test 22", |
|
162 version: "5", |
|
163 start: false, |
|
164 appBlocks: true, |
|
165 toolkitBlocks: true |
|
166 }, { |
|
167 id: "test_bug449027_23@tests.mozilla.org", |
|
168 name: "Bug 449027 Addon Test 23", |
|
169 version: "5", |
|
170 start: false, |
|
171 appBlocks: true, |
|
172 toolkitBlocks: true |
|
173 }, { |
|
174 id: "test_bug449027_24@tests.mozilla.org", |
|
175 name: "Bug 449027 Addon Test 24", |
|
176 version: "5", |
|
177 start: false, |
|
178 appBlocks: true, |
|
179 toolkitBlocks: true |
|
180 }, { |
|
181 id: "test_bug449027_25@tests.mozilla.org", |
|
182 name: "Bug 449027 Addon Test 25", |
|
183 version: "5", |
|
184 start: false, |
|
185 appBlocks: true, |
|
186 toolkitBlocks: true |
|
187 }]; |
|
188 |
|
189 function MockPluginTag(name, version, start, appBlocks, toolkitBlocks) |
|
190 { |
|
191 this.name = name; |
|
192 this.version = version; |
|
193 this.start = start; |
|
194 this.appBlocks = appBlocks; |
|
195 this.toolkitBlocks = toolkitBlocks; |
|
196 } |
|
197 Object.defineProperty(MockPluginTag.prototype, "blocklisted", { |
|
198 get: function MockPluginTag_getBlocklisted() { |
|
199 let bls = AM_Cc["@mozilla.org/extensions/blocklist;1"].getService(Ci.nsIBlocklistService); |
|
200 return bls.getPluginBlocklistState(this) == bls.STATE_BLOCKED; |
|
201 } |
|
202 }); |
|
203 |
|
204 var PLUGINS = [ |
|
205 new MockPluginTag("test_bug449027_1", "5", false, false, false), |
|
206 new MockPluginTag("test_bug449027_2", "5", false, true, false), |
|
207 new MockPluginTag("test_bug449027_3", "5", false, true, false), |
|
208 new MockPluginTag("test_bug449027_4", "5", false, false, false), |
|
209 new MockPluginTag("test_bug449027_5", "5", false, false, false), |
|
210 new MockPluginTag("test_bug449027_6", "5", false, true, false), |
|
211 new MockPluginTag("test_bug449027_7", "5", false, true, false), |
|
212 new MockPluginTag("test_bug449027_8", "5", false, true, false), |
|
213 new MockPluginTag("test_bug449027_9", "5", false, true, false), |
|
214 new MockPluginTag("test_bug449027_10", "5", false, true, false), |
|
215 new MockPluginTag("test_bug449027_11", "5", false, true, false), |
|
216 new MockPluginTag("test_bug449027_12", "5", false, true, false), |
|
217 new MockPluginTag("test_bug449027_13", "5", false, true, false), |
|
218 new MockPluginTag("test_bug449027_14", "5", false, false, false), |
|
219 new MockPluginTag("test_bug449027_15", "5", false, true, true), |
|
220 new MockPluginTag("test_bug449027_16", "5", false, true, true), |
|
221 new MockPluginTag("test_bug449027_17", "5", false, false, false), |
|
222 new MockPluginTag("test_bug449027_18", "5", false, false, false), |
|
223 new MockPluginTag("test_bug449027_19", "5", false, true, true), |
|
224 new MockPluginTag("test_bug449027_20", "5", false, true, true), |
|
225 new MockPluginTag("test_bug449027_21", "5", false, true, true), |
|
226 new MockPluginTag("test_bug449027_22", "5", false, true, true), |
|
227 new MockPluginTag("test_bug449027_23", "5", false, true, true), |
|
228 new MockPluginTag("test_bug449027_24", "5", false, true, true), |
|
229 new MockPluginTag("test_bug449027_25", "5", false, true, true) |
|
230 ]; |
|
231 |
|
232 var gCallback = null; |
|
233 var gTestserver = null; |
|
234 var gNewBlocks = []; |
|
235 |
|
236 // A fake plugin host for the blocklist service to use |
|
237 var PluginHost = { |
|
238 getPluginTags: function(countRef) { |
|
239 countRef.value = PLUGINS.length; |
|
240 return PLUGINS; |
|
241 }, |
|
242 |
|
243 QueryInterface: function(iid) { |
|
244 if (iid.equals(Ci.nsIPluginHost) |
|
245 || iid.equals(Ci.nsISupports)) |
|
246 return this; |
|
247 |
|
248 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
249 } |
|
250 } |
|
251 |
|
252 var PluginHostFactory = { |
|
253 createInstance: function (outer, iid) { |
|
254 if (outer != null) |
|
255 throw Components.results.NS_ERROR_NO_AGGREGATION; |
|
256 return PluginHost.QueryInterface(iid); |
|
257 } |
|
258 }; |
|
259 |
|
260 // Don't need the full interface, attempts to call other methods will just |
|
261 // throw which is just fine |
|
262 var WindowWatcher = { |
|
263 openWindow: function(parent, url, name, features, arguments) { |
|
264 // Should be called to list the newly blocklisted items |
|
265 do_check_eq(url, URI_EXTENSION_BLOCKLIST_DIALOG); |
|
266 do_check_neq(gCallback, null); |
|
267 |
|
268 var args = arguments.wrappedJSObject; |
|
269 |
|
270 gNewBlocks = []; |
|
271 var list = args.list; |
|
272 for (let listItem of list) |
|
273 gNewBlocks.push(listItem.name + " " + listItem.version); |
|
274 |
|
275 // Call the callback after the blocklist has finished up |
|
276 do_timeout(0, gCallback); |
|
277 }, |
|
278 |
|
279 QueryInterface: function(iid) { |
|
280 if (iid.equals(Ci.nsIWindowWatcher) |
|
281 || iid.equals(Ci.nsISupports)) |
|
282 return this; |
|
283 |
|
284 throw Components.results.NS_ERROR_NO_INTERFACE; |
|
285 } |
|
286 } |
|
287 |
|
288 var WindowWatcherFactory = { |
|
289 createInstance: function createInstance(outer, iid) { |
|
290 if (outer != null) |
|
291 throw Components.results.NS_ERROR_NO_AGGREGATION; |
|
292 return WindowWatcher.QueryInterface(iid); |
|
293 } |
|
294 }; |
|
295 var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); |
|
296 registrar.registerFactory(Components.ID("{721c3e73-969e-474b-a6dc-059fd288c428}"), |
|
297 "Fake Plugin Host", |
|
298 "@mozilla.org/plugin/host;1", PluginHostFactory); |
|
299 registrar.registerFactory(Components.ID("{1dfeb90a-2193-45d5-9cb8-864928b2af55}"), |
|
300 "Fake Window Watcher", |
|
301 "@mozilla.org/embedcomp/window-watcher;1", WindowWatcherFactory); |
|
302 |
|
303 function create_addon(addon) { |
|
304 var installrdf = "<?xml version=\"1.0\"?>\n" + |
|
305 "\n" + |
|
306 "<RDF xmlns=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n" + |
|
307 " xmlns:em=\"http://www.mozilla.org/2004/em-rdf#\">\n" + |
|
308 " <Description about=\"urn:mozilla:install-manifest\">\n" + |
|
309 " <em:id>" + addon.id + "</em:id>\n" + |
|
310 " <em:version>" + addon.version + "</em:version>\n" + |
|
311 " <em:targetApplication>\n" + |
|
312 " <Description>\n" + |
|
313 " <em:id>xpcshell@tests.mozilla.org</em:id>\n" + |
|
314 " <em:minVersion>3</em:minVersion>\n" + |
|
315 " <em:maxVersion>3</em:maxVersion>\n" + |
|
316 " </Description>\n" + |
|
317 " </em:targetApplication>\n" + |
|
318 " <em:name>" + addon.name + "</em:name>\n" + |
|
319 " </Description>\n" + |
|
320 "</RDF>\n"; |
|
321 var target = gProfD.clone(); |
|
322 target.append("extensions"); |
|
323 target.append(addon.id); |
|
324 target.append("install.rdf"); |
|
325 target.create(target.NORMAL_FILE_TYPE, 0644); |
|
326 var stream = Components.classes["@mozilla.org/network/file-output-stream;1"] |
|
327 .createInstance(Ci.nsIFileOutputStream); |
|
328 stream.init(target, 0x04 | 0x08 | 0x20, 0664, 0); // write, create, truncate |
|
329 stream.write(installrdf, installrdf.length); |
|
330 stream.close(); |
|
331 } |
|
332 |
|
333 /** |
|
334 * Checks that items are blocklisted correctly according to the current test. |
|
335 * If a lastTest is provided checks that the notification dialog got passed |
|
336 * the newly blocked items compared to the previous test. |
|
337 */ |
|
338 function check_state(test, lastTest, callback) { |
|
339 AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], function(addons) { |
|
340 for (var i = 0; i < ADDONS.length; i++) { |
|
341 var blocked = addons[i].blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED; |
|
342 if (blocked != ADDONS[i][test]) |
|
343 do_throw("Blocklist state did not match expected for extension " + (i + 1) + ", test " + test); |
|
344 } |
|
345 |
|
346 for (i = 0; i < PLUGINS.length; i++) { |
|
347 if (PLUGINS[i].blocklisted != PLUGINS[i][test]) |
|
348 do_throw("Blocklist state did not match expected for plugin " + (i + 1) + ", test " + test); |
|
349 } |
|
350 |
|
351 if (lastTest) { |
|
352 var expected = 0; |
|
353 for (i = 0; i < ADDONS.length; i++) { |
|
354 if (ADDONS[i][test] && !ADDONS[i][lastTest]) { |
|
355 if (gNewBlocks.indexOf(ADDONS[i].name + " " + ADDONS[i].version) < 0) |
|
356 do_throw("Addon " + (i + 1) + " should have been listed in the blocklist notification for test " + test); |
|
357 expected++; |
|
358 } |
|
359 } |
|
360 |
|
361 for (i = 0; i < PLUGINS.length; i++) { |
|
362 if (PLUGINS[i][test] && !PLUGINS[i][lastTest]) { |
|
363 if (gNewBlocks.indexOf(PLUGINS[i].name + " " + PLUGINS[i].version) < 0) |
|
364 do_throw("Plugin " + (i + 1) + " should have been listed in the blocklist notification for test " + test); |
|
365 expected++; |
|
366 } |
|
367 } |
|
368 |
|
369 do_check_eq(expected, gNewBlocks.length); |
|
370 } |
|
371 do_execute_soon(callback); |
|
372 }); |
|
373 } |
|
374 |
|
375 function load_blocklist(file) { |
|
376 Services.prefs.setCharPref("extensions.blocklist.url", "http://localhost:" + gPort + "/data/" + file); |
|
377 var blocklist = Components.classes["@mozilla.org/extensions/blocklist;1"] |
|
378 .getService(Ci.nsITimerCallback); |
|
379 blocklist.notify(null); |
|
380 } |
|
381 |
|
382 function run_test() { |
|
383 // Setup for test |
|
384 dump("Setting up tests\n"); |
|
385 // Rather than keeping lots of identical add-ons in version control, just |
|
386 // write them into the profile. |
|
387 for (let addon of ADDONS) |
|
388 create_addon(addon); |
|
389 |
|
390 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "3", "8"); |
|
391 startupManager(); |
|
392 |
|
393 gTestserver = new HttpServer(); |
|
394 gTestserver.registerDirectory("/data/", do_get_file("data")); |
|
395 gTestserver.start(-1); |
|
396 gPort = gTestserver.identity.primaryPort; |
|
397 |
|
398 do_test_pending(); |
|
399 check_test_pt1(); |
|
400 } |
|
401 |
|
402 /** |
|
403 * Checks the initial state is correct |
|
404 */ |
|
405 function check_test_pt1() { |
|
406 dump("Checking pt 1\n"); |
|
407 |
|
408 AddonManager.getAddonsByIDs([a.id for each (a in ADDONS)], function(addons) { |
|
409 for (var i = 0; i < ADDONS.length; i++) { |
|
410 if (!addons[i]) |
|
411 do_throw("Addon " + (i + 1) + " did not get installed correctly"); |
|
412 } |
|
413 |
|
414 do_execute_soon(function checkstate1() {check_state("start", null, run_test_pt2);}); |
|
415 }); |
|
416 } |
|
417 |
|
418 /** |
|
419 * Load the toolkit based blocks |
|
420 */ |
|
421 function run_test_pt2() { |
|
422 dump("Running test pt 2\n"); |
|
423 gCallback = check_test_pt2; |
|
424 load_blocklist("test_bug449027_toolkit.xml"); |
|
425 } |
|
426 |
|
427 function check_test_pt2() { |
|
428 dump("Checking pt 2\n"); |
|
429 check_state("toolkitBlocks", "start", run_test_pt3); |
|
430 } |
|
431 |
|
432 /** |
|
433 * Load the application based blocks |
|
434 */ |
|
435 function run_test_pt3() { |
|
436 dump("Running test pt 3\n"); |
|
437 gCallback = check_test_pt3; |
|
438 load_blocklist("test_bug449027_app.xml"); |
|
439 } |
|
440 |
|
441 function check_test_pt3() { |
|
442 dump("Checking pt 3\n"); |
|
443 check_state("appBlocks", "toolkitBlocks", end_test); |
|
444 } |
|
445 |
|
446 function end_test() { |
|
447 gTestserver.stop(do_test_finished); |
|
448 } |