Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* Any copyright is dedicated to the Public Domain.
2 * http://creativecommons.org/publicdomain/zero/1.0/
3 */
5 // This verifies that add-on update checks work
7 const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
8 const PREF_SELECTED_LOCALE = "general.useragent.locale";
9 const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
11 // The test extension uses an insecure update url.
12 Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
13 Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
14 // This test requires lightweight themes update to be enabled even if the app
15 // doesn't support lightweight themes.
16 Services.prefs.setBoolPref("lightweightThemes.update.enabled", true);
18 Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm");
20 const PARAMS = "?%REQ_VERSION%/%ITEM_ID%/%ITEM_VERSION%/%ITEM_MAXAPPVERSION%/" +
21 "%ITEM_STATUS%/%APP_ID%/%APP_VERSION%/%CURRENT_APP_VERSION%/" +
22 "%APP_OS%/%APP_ABI%/%APP_LOCALE%/%UPDATE_TYPE%";
24 var gInstallDate;
26 Components.utils.import("resource://testing-common/httpd.js");
27 var testserver = new HttpServer();
28 testserver.start(-1);
29 gPort = testserver.identity.primaryPort;
30 mapFile("/data/test_update.rdf", testserver);
31 mapFile("/data/test_update.xml", testserver);
32 testserver.registerDirectory("/addons/", do_get_file("addons"));
34 const profileDir = gProfD.clone();
35 profileDir.append("extensions");
37 let originalSyncGUID;
39 function run_test() {
40 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
41 Services.prefs.setBoolPref(PREF_MATCH_OS_LOCALE, false);
42 Services.prefs.setCharPref(PREF_SELECTED_LOCALE, "fr-FR");
44 writeInstallRDFForExtension({
45 id: "addon1@tests.mozilla.org",
46 version: "1.0",
47 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
48 targetApplications: [{
49 id: "xpcshell@tests.mozilla.org",
50 minVersion: "1",
51 maxVersion: "1"
52 }],
53 name: "Test Addon 1",
54 }, profileDir);
56 writeInstallRDFForExtension({
57 id: "addon2@tests.mozilla.org",
58 version: "1.0",
59 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
60 targetApplications: [{
61 id: "xpcshell@tests.mozilla.org",
62 minVersion: "0",
63 maxVersion: "0"
64 }],
65 name: "Test Addon 2",
66 }, profileDir);
68 writeInstallRDFForExtension({
69 id: "addon3@tests.mozilla.org",
70 version: "1.0",
71 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
72 targetApplications: [{
73 id: "xpcshell@tests.mozilla.org",
74 minVersion: "5",
75 maxVersion: "5"
76 }],
77 name: "Test Addon 3",
78 }, profileDir);
80 startupManager();
82 do_test_pending();
83 run_test_1();
84 }
86 function end_test() {
87 testserver.stop(do_test_finished);
88 }
90 // Verify that an update is available and can be installed.
91 function run_test_1() {
92 AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
93 do_check_neq(a1, null);
94 do_check_eq(a1.version, "1.0");
95 do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
96 do_check_eq(a1.releaseNotesURI, null);
97 do_check_true(a1.foreignInstall);
98 do_check_neq(a1.syncGUID, null);
100 originalSyncGUID = a1.syncGUID;
101 a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
103 prepare_test({
104 "addon1@tests.mozilla.org": [
105 ["onPropertyChanged", ["applyBackgroundUpdates"]]
106 ]
107 });
108 a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
109 check_test_completed();
111 a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
113 prepare_test({}, [
114 "onNewInstall",
115 ]);
117 a1.findUpdates({
118 onNoCompatibilityUpdateAvailable: function(addon) {
119 do_throw("Should not have seen onNoCompatibilityUpdateAvailable notification");
120 },
122 onUpdateAvailable: function(addon, install) {
123 ensure_test_completed();
125 AddonManager.getAllInstalls(function(aInstalls) {
126 do_check_eq(aInstalls.length, 1);
127 do_check_eq(aInstalls[0], install);
129 do_check_eq(addon, a1);
130 do_check_eq(install.name, addon.name);
131 do_check_eq(install.version, "2.0");
132 do_check_eq(install.state, AddonManager.STATE_AVAILABLE);
133 do_check_eq(install.existingAddon, addon);
134 do_check_eq(install.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
136 // Verify that another update check returns the same AddonInstall
137 a1.findUpdates({
138 onNoCompatibilityUpdateAvailable: function(addon) {
139 do_throw("Should not have seen onNoCompatibilityUpdateAvailable notification");
140 },
142 onUpdateAvailable: function(newAddon, newInstall) {
143 AddonManager.getAllInstalls(function(aInstalls) {
144 do_check_eq(aInstalls.length, 1);
145 do_check_eq(aInstalls[0], install);
146 do_check_eq(newAddon, addon);
147 do_check_eq(newInstall, install);
149 prepare_test({}, [
150 "onDownloadStarted",
151 "onDownloadEnded",
152 ], check_test_1);
153 install.install();
154 });
155 },
157 onNoUpdateAvailable: function(addon) {
158 do_throw("Should not have seen onNoUpdateAvailable notification");
159 }
160 }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
161 });
162 },
164 onNoUpdateAvailable: function(addon) {
165 do_throw("Should not have seen onNoUpdateAvailable notification");
166 }
167 }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
168 });
169 }
171 function check_test_1(install) {
172 ensure_test_completed();
173 do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
174 run_test_2(install);
175 return false;
176 }
178 // Continue installing the update.
179 function run_test_2(install) {
180 // Verify that another update check returns no new update
181 install.existingAddon.findUpdates({
182 onNoCompatibilityUpdateAvailable: function(addon) {
183 do_throw("Should not have seen onNoCompatibilityUpdateAvailable notification");
184 },
186 onUpdateAvailable: function(addon, install) {
187 do_throw("Should find no available update when one is already downloading");
188 },
190 onNoUpdateAvailable: function(addon) {
191 AddonManager.getAllInstalls(function(aInstalls) {
192 do_check_eq(aInstalls.length, 1);
193 do_check_eq(aInstalls[0], install);
195 prepare_test({
196 "addon1@tests.mozilla.org": [
197 "onInstalling"
198 ]
199 }, [
200 "onInstallStarted",
201 "onInstallEnded",
202 ], check_test_2);
203 install.install();
204 });
205 }
206 }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
207 }
209 function check_test_2() {
210 ensure_test_completed();
212 AddonManager.getAddonByID("addon1@tests.mozilla.org", callback_soon(function(olda1) {
213 do_check_neq(olda1, null);
214 do_check_eq(olda1.version, "1.0");
215 do_check_true(isExtensionInAddonsList(profileDir, olda1.id));
217 shutdownManager();
219 startupManager();
221 do_check_true(isExtensionInAddonsList(profileDir, olda1.id));
223 AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
224 do_check_neq(a1, null);
225 do_check_eq(a1.version, "2.0");
226 do_check_true(isExtensionInAddonsList(profileDir, a1.id));
227 do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE);
228 do_check_eq(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
229 do_check_true(a1.foreignInstall);
230 do_check_neq(a1.syncGUID, null);
231 do_check_eq(originalSyncGUID, a1.syncGUID);
233 a1.uninstall();
234 do_execute_soon(run_test_3);
235 });
236 }));
237 }
240 // Check that an update check finds compatibility updates and applies them
241 function run_test_3() {
242 restartManager();
244 AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
245 do_check_neq(a2, null);
246 do_check_true(a2.isActive);
247 do_check_true(a2.isCompatible);
248 do_check_false(a2.appDisabled);
249 do_check_true(a2.isCompatibleWith("0"));
251 a2.findUpdates({
252 onCompatibilityUpdateAvailable: function(addon) {
253 do_check_true(a2.isCompatible);
254 do_check_false(a2.appDisabled);
255 do_check_true(a2.isActive);
256 },
258 onUpdateAvailable: function(addon, install) {
259 do_throw("Should not have seen an available update");
260 },
262 onNoUpdateAvailable: function(addon) {
263 do_check_eq(addon, a2);
264 do_execute_soon(check_test_3);
265 }
266 }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
267 });
268 }
270 function check_test_3() {
271 restartManager();
272 AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
273 do_check_neq(a2, null);
274 do_check_true(a2.isActive);
275 do_check_true(a2.isCompatible);
276 do_check_false(a2.appDisabled);
277 a2.uninstall();
279 run_test_4();
280 });
281 }
283 // Checks that we see no compatibility information when there is none.
284 function run_test_4() {
285 AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
286 do_check_neq(a3, null);
287 do_check_false(a3.isActive);
288 do_check_false(a3.isCompatible);
289 do_check_true(a3.appDisabled);
290 do_check_true(a3.isCompatibleWith("5"));
291 do_check_false(a3.isCompatibleWith("2"));
293 a3.findUpdates({
294 sawUpdate: false,
295 onCompatibilityUpdateAvailable: function(addon) {
296 do_throw("Should not have seen compatibility information");
297 },
299 onNoCompatibilityUpdateAvailable: function(addon) {
300 this.sawUpdate = true;
301 },
303 onUpdateAvailable: function(addon, install) {
304 do_throw("Should not have seen an available update");
305 },
307 onNoUpdateAvailable: function(addon) {
308 do_check_true(this.sawUpdate);
309 run_test_5();
310 }
311 }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
312 });
313 }
315 // Checks that compatibility info for future apps are detected but don't make
316 // the item compatibile.
317 function run_test_5() {
318 AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
319 do_check_neq(a3, null);
320 do_check_false(a3.isActive);
321 do_check_false(a3.isCompatible);
322 do_check_true(a3.appDisabled);
323 do_check_true(a3.isCompatibleWith("5"));
324 do_check_false(a3.isCompatibleWith("2"));
326 a3.findUpdates({
327 sawUpdate: false,
328 onCompatibilityUpdateAvailable: function(addon) {
329 do_check_false(a3.isCompatible);
330 do_check_true(a3.appDisabled);
331 do_check_false(a3.isActive);
332 this.sawUpdate = true;
333 },
335 onNoCompatibilityUpdateAvailable: function(addon) {
336 do_throw("Should have seen some compatibility information");
337 },
339 onUpdateAvailable: function(addon, install) {
340 do_throw("Should not have seen an available update");
341 },
343 onNoUpdateAvailable: function(addon) {
344 do_check_true(this.sawUpdate);
345 do_execute_soon(check_test_5);
346 }
347 }, AddonManager.UPDATE_WHEN_USER_REQUESTED, "3.0");
348 });
349 }
351 function check_test_5() {
352 restartManager();
353 AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
354 do_check_neq(a3, null);
355 do_check_false(a3.isActive);
356 do_check_false(a3.isCompatible);
357 do_check_true(a3.appDisabled);
359 a3.uninstall();
360 do_execute_soon(run_test_6);
361 });
362 }
364 // Test that background update checks work
365 function run_test_6() {
366 restartManager();
368 writeInstallRDFForExtension({
369 id: "addon1@tests.mozilla.org",
370 version: "1.0",
371 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
372 targetApplications: [{
373 id: "xpcshell@tests.mozilla.org",
374 minVersion: "1",
375 maxVersion: "1"
376 }],
377 name: "Test Addon 1",
378 }, profileDir);
379 restartManager();
381 prepare_test({}, [
382 "onNewInstall",
383 "onDownloadStarted",
384 "onDownloadEnded"
385 ], continue_test_6);
387 // Fake a timer event to cause a background update and wait for the magic to
388 // happen
389 gInternalManager.notify(null);
390 }
392 function continue_test_6(install) {
393 do_check_neq(install.existingAddon, null);
394 do_check_eq(install.existingAddon.id, "addon1@tests.mozilla.org");
396 prepare_test({
397 "addon1@tests.mozilla.org": [
398 "onInstalling"
399 ]
400 }, [
401 "onInstallStarted",
402 "onInstallEnded",
403 ], callback_soon(check_test_6));
404 }
406 function check_test_6(install) {
407 do_check_eq(install.existingAddon.pendingUpgrade.install, install);
409 restartManager();
410 AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
411 do_check_neq(a1, null);
412 do_check_eq(a1.version, "2.0");
413 do_check_eq(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
414 a1.uninstall();
415 do_execute_soon(run_test_7);
416 });
417 }
419 // Test that background update checks work for lightweight themes
420 function run_test_7() {
421 restartManager();
423 LightweightThemeManager.currentTheme = {
424 id: "1",
425 version: "1",
426 name: "Test LW Theme",
427 description: "A test theme",
428 author: "Mozilla",
429 homepageURL: "http://localhost:" + gPort + "/data/index.html",
430 headerURL: "http://localhost:" + gPort + "/data/header.png",
431 footerURL: "http://localhost:" + gPort + "/data/footer.png",
432 previewURL: "http://localhost:" + gPort + "/data/preview.png",
433 iconURL: "http://localhost:" + gPort + "/data/icon.png",
434 updateURL: "http://localhost:" + gPort + "/data/lwtheme.js"
435 };
437 // XXX The lightweight theme manager strips non-https updateURLs so hack it
438 // back in.
439 let themes = JSON.parse(Services.prefs.getCharPref("lightweightThemes.usedThemes"));
440 do_check_eq(themes.length, 1);
441 themes[0].updateURL = "http://localhost:" + gPort + "/data/lwtheme.js";
442 Services.prefs.setCharPref("lightweightThemes.usedThemes", JSON.stringify(themes));
444 testserver.registerPathHandler("/data/lwtheme.js", function(request, response) {
445 // Server will specify an expiry in one year.
446 let expiry = new Date();
447 expiry.setFullYear(expiry.getFullYear() + 1);
448 response.setHeader("Expires", expiry.toUTCString(), false);
449 response.write(JSON.stringify({
450 id: "1",
451 version: "2",
452 name: "Updated Theme",
453 description: "A test theme",
454 author: "Mozilla",
455 homepageURL: "http://localhost:" + gPort + "/data/index2.html",
456 headerURL: "http://localhost:" + gPort + "/data/header.png",
457 footerURL: "http://localhost:" + gPort + "/data/footer.png",
458 previewURL: "http://localhost:" + gPort + "/data/preview.png",
459 iconURL: "http://localhost:" + gPort + "/data/icon2.png",
460 updateURL: "http://localhost:" + gPort + "/data/lwtheme.js"
461 }));
462 });
464 AddonManager.getAddonByID("1@personas.mozilla.org", function(p1) {
465 do_check_neq(p1, null);
466 do_check_eq(p1.version, "1");
467 do_check_eq(p1.name, "Test LW Theme");
468 do_check_true(p1.isActive);
469 do_check_eq(p1.installDate.getTime(), p1.updateDate.getTime());
471 // 5 seconds leeway seems like a lot, but tests can run slow and really if
472 // this is within 5 seconds it is fine. If it is going to be wrong then it
473 // is likely to be hours out at least
474 do_check_true((Date.now() - p1.installDate.getTime()) < 5000);
476 gInstallDate = p1.installDate.getTime();
478 prepare_test({
479 "1@personas.mozilla.org": [
480 ["onInstalling", false],
481 "onInstalled"
482 ]
483 }, [
484 "onExternalInstall"
485 ], check_test_7);
487 // Fake a timer event to cause a background update and wait for the magic to
488 // happen
489 gInternalManager.notify(null);
490 });
491 }
493 function check_test_7() {
494 AddonManager.getAddonByID("1@personas.mozilla.org", function(p1) {
495 do_check_neq(p1, null);
496 do_check_eq(p1.version, "2");
497 do_check_eq(p1.name, "Updated Theme");
498 do_check_eq(p1.installDate.getTime(), gInstallDate);
499 do_check_true(p1.installDate.getTime() < p1.updateDate.getTime());
501 // 5 seconds leeway seems like a lot, but tests can run slow and really if
502 // this is within 5 seconds it is fine. If it is going to be wrong then it
503 // is likely to be hours out at least
504 do_check_true((Date.now() - p1.updateDate.getTime()) < 5000);
506 gInstallDate = p1.installDate.getTime();
508 run_test_7_cache();
509 });
510 }
512 // Test that background update checks for lightweight themes do not use the cache
513 // The update body from test 7 shouldn't be used since the cache should be bypassed.
514 function run_test_7_cache() {
515 // XXX The lightweight theme manager strips non-https updateURLs so hack it
516 // back in.
517 let themes = JSON.parse(Services.prefs.getCharPref("lightweightThemes.usedThemes"));
518 do_check_eq(themes.length, 1);
519 themes[0].updateURL = "http://localhost:" + gPort + "/data/lwtheme.js";
520 Services.prefs.setCharPref("lightweightThemes.usedThemes", JSON.stringify(themes));
522 testserver.registerPathHandler("/data/lwtheme.js", function(request, response) {
523 response.write(JSON.stringify({
524 id: "1",
525 version: "3",
526 name: "Updated Theme v.3",
527 description: "A test theme v.3",
528 author: "John Smith",
529 homepageURL: "http://localhost:" + gPort + "/data/index3.html?v=3",
530 headerURL: "http://localhost:" + gPort + "/data/header.png?v=3",
531 footerURL: "http://localhost:" + gPort + "/data/footer.png?v=3",
532 previewURL: "http://localhost:" + gPort + "/data/preview.png?v=3",
533 iconURL: "http://localhost:" + gPort + "/data/icon2.png?v=3",
534 updateURL: "https://localhost:" + gPort + "/data/lwtheme.js?v=3"
535 }));
536 });
538 AddonManager.getAddonByID("1@personas.mozilla.org", function(p1) {
539 do_check_neq(p1, null);
540 do_check_eq(p1.version, "2");
541 do_check_eq(p1.name, "Updated Theme");
542 do_check_true(p1.isActive);
543 do_check_eq(p1.installDate.getTime(), gInstallDate);
544 do_check_true(p1.installDate.getTime() < p1.updateDate.getTime());
546 prepare_test({
547 "1@personas.mozilla.org": [
548 ["onInstalling", false],
549 "onInstalled"
550 ]
551 }, [
552 "onExternalInstall"
553 ], check_test_7_cache);
555 // Fake a timer event to cause a background update and wait for the magic to
556 // happen
557 gInternalManager.notify(null);
558 });
559 }
561 function check_test_7_cache() {
562 AddonManager.getAddonByID("1@personas.mozilla.org", function(p1) {
563 let currentTheme = LightweightThemeManager.currentTheme;
564 do_check_neq(p1, null);
565 do_check_eq(p1.version, "3");
566 do_check_eq(p1.name, "Updated Theme v.3");
567 do_check_eq(p1.description, "A test theme v.3");
568 do_print(JSON.stringify(p1));
569 do_check_eq(p1.creator.name, "John Smith");
570 do_check_eq(p1.homepageURL, "http://localhost:" + gPort + "/data/index3.html?v=3");
571 do_check_eq(p1.screenshots[0].url, "http://localhost:" + gPort + "/data/preview.png?v=3");
572 do_check_eq(p1.iconURL, "http://localhost:" + gPort + "/data/icon2.png?v=3");
573 do_check_eq(currentTheme.headerURL, "http://localhost:" + gPort + "/data/header.png?v=3");
574 do_check_eq(currentTheme.footerURL, "http://localhost:" + gPort + "/data/footer.png?v=3");
575 do_check_eq(currentTheme.updateURL, "https://localhost:" + gPort + "/data/lwtheme.js?v=3");
577 do_check_eq(p1.installDate.getTime(), gInstallDate);
578 do_check_true(p1.installDate.getTime() < p1.updateDate.getTime());
580 do_execute_soon(run_test_8);
581 });
582 }
584 // Verify the parameter escaping in update urls.
585 function run_test_8() {
586 writeInstallRDFForExtension({
587 id: "addon1@tests.mozilla.org",
588 version: "5.0",
589 updateURL: "http://localhost:" + gPort + "/data/param_test.rdf" + PARAMS,
590 targetApplications: [{
591 id: "xpcshell@tests.mozilla.org",
592 minVersion: "1",
593 maxVersion: "2"
594 }],
595 name: "Test Addon 1",
596 }, profileDir);
598 writeInstallRDFForExtension({
599 id: "addon2@tests.mozilla.org",
600 version: "67.0.5b1",
601 updateURL: "http://localhost:" + gPort + "/data/param_test.rdf" + PARAMS,
602 targetApplications: [{
603 id: "toolkit@mozilla.org",
604 minVersion: "0",
605 maxVersion: "3"
606 }],
607 name: "Test Addon 2",
608 }, profileDir);
610 writeInstallRDFForExtension({
611 id: "addon3@tests.mozilla.org",
612 version: "1.3+",
613 updateURL: "http://localhost:" + gPort + "/data/param_test.rdf" + PARAMS,
614 targetApplications: [{
615 id: "xpcshell@tests.mozilla.org",
616 minVersion: "0",
617 maxVersion: "0"
618 }, {
619 id: "toolkit@mozilla.org",
620 minVersion: "0",
621 maxVersion: "3"
622 }],
623 name: "Test Addon 3",
624 }, profileDir);
626 writeInstallRDFForExtension({
627 id: "addon4@tests.mozilla.org",
628 version: "0.5ab6",
629 updateURL: "http://localhost:" + gPort + "/data/param_test.rdf" + PARAMS,
630 targetApplications: [{
631 id: "xpcshell@tests.mozilla.org",
632 minVersion: "1",
633 maxVersion: "5"
634 }],
635 name: "Test Addon 4",
636 }, profileDir);
638 writeInstallRDFForExtension({
639 id: "addon5@tests.mozilla.org",
640 version: "1.0",
641 updateURL: "http://localhost:" + gPort + "/data/param_test.rdf" + PARAMS,
642 targetApplications: [{
643 id: "xpcshell@tests.mozilla.org",
644 minVersion: "1",
645 maxVersion: "1"
646 }],
647 name: "Test Addon 5",
648 }, profileDir);
650 writeInstallRDFForExtension({
651 id: "addon6@tests.mozilla.org",
652 version: "1.0",
653 updateURL: "http://localhost:" + gPort + "/data/param_test.rdf" + PARAMS,
654 targetApplications: [{
655 id: "xpcshell@tests.mozilla.org",
656 minVersion: "1",
657 maxVersion: "1"
658 }],
659 name: "Test Addon 6",
660 }, profileDir);
662 restartManager();
664 AddonManager.getAddonByID("addon2@tests.mozilla.org", callback_soon(function(a2) {
665 a2.userDisabled = true;
666 restartManager();
668 testserver.registerPathHandler("/data/param_test.rdf", function(request, response) {
669 do_check_neq(request.queryString, "");
670 let [req_version, item_id, item_version,
671 item_maxappversion, item_status,
672 app_id, app_version, current_app_version,
673 app_os, app_abi, app_locale, update_type] =
674 [decodeURIComponent(a) for each (a in request.queryString.split("/"))];
676 do_check_eq(req_version, "2");
678 switch(item_id) {
679 case "addon1@tests.mozilla.org":
680 do_check_eq(item_version, "5.0");
681 do_check_eq(item_maxappversion, "2");
682 do_check_eq(item_status, "userEnabled");
683 do_check_eq(app_version, "1");
684 do_check_eq(update_type, "97");
685 break;
686 case "addon2@tests.mozilla.org":
687 do_check_eq(item_version, "67.0.5b1");
688 do_check_eq(item_maxappversion, "3");
689 do_check_eq(item_status, "userDisabled");
690 do_check_eq(app_version, "1");
691 do_check_eq(update_type, "49");
692 break;
693 case "addon3@tests.mozilla.org":
694 do_check_eq(item_version, "1.3+");
695 do_check_eq(item_maxappversion, "0");
696 do_check_eq(item_status, "userEnabled");
697 do_check_eq(app_version, "1");
698 do_check_eq(update_type, "112");
699 break;
700 case "addon4@tests.mozilla.org":
701 do_check_eq(item_version, "0.5ab6");
702 do_check_eq(item_maxappversion, "5");
703 do_check_eq(item_status, "userEnabled");
704 do_check_eq(app_version, "2");
705 do_check_eq(update_type, "98");
706 break;
707 case "addon5@tests.mozilla.org":
708 do_check_eq(item_version, "1.0");
709 do_check_eq(item_maxappversion, "1");
710 do_check_eq(item_status, "userEnabled");
711 do_check_eq(app_version, "1");
712 do_check_eq(update_type, "35");
713 break;
714 case "addon6@tests.mozilla.org":
715 do_check_eq(item_version, "1.0");
716 do_check_eq(item_maxappversion, "1");
717 do_check_eq(item_status, "userEnabled");
718 do_check_eq(app_version, "1");
719 do_check_eq(update_type, "99");
720 break;
721 default:
722 do_throw("Update request for unexpected add-on " + item_id);
723 }
725 do_check_eq(app_id, "xpcshell@tests.mozilla.org");
726 do_check_eq(current_app_version, "1");
727 do_check_eq(app_os, "XPCShell");
728 do_check_eq(app_abi, "noarch-spidermonkey");
729 do_check_eq(app_locale, "fr-FR");
731 request.setStatusLine(null, 500, "Server Error");
732 });
734 AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
735 "addon2@tests.mozilla.org",
736 "addon3@tests.mozilla.org",
737 "addon4@tests.mozilla.org",
738 "addon5@tests.mozilla.org",
739 "addon6@tests.mozilla.org"],
740 function([a1, a2, a3, a4, a5, a6]) {
741 let count = 6;
743 function run_next_test() {
744 a1.uninstall();
745 a2.uninstall();
746 a3.uninstall();
747 a4.uninstall();
748 a5.uninstall();
749 a6.uninstall();
751 restartManager();
752 run_test_9();
753 }
755 let compatListener = {
756 onUpdateFinished: function(addon, error) {
757 if (--count == 0)
758 do_execute_soon(run_next_test);
759 }
760 };
762 let updateListener = {
763 onUpdateAvailable: function(addon, update) {
764 // Dummy so the update checker knows we care about new versions
765 },
767 onUpdateFinished: function(addon, error) {
768 if (--count == 0)
769 do_execute_soon(run_next_test);
770 }
771 };
773 a1.findUpdates(updateListener, AddonManager.UPDATE_WHEN_USER_REQUESTED);
774 a2.findUpdates(compatListener, AddonManager.UPDATE_WHEN_ADDON_INSTALLED);
775 a3.findUpdates(updateListener, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
776 a4.findUpdates(updateListener, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED, "2");
777 a5.findUpdates(compatListener, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
778 a6.findUpdates(updateListener, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
779 });
780 }));
781 }
783 // Tests that if an install.rdf claims compatibility then the add-on will be
784 // seen as compatible regardless of what the update.rdf says.
785 function run_test_9() {
786 writeInstallRDFForExtension({
787 id: "addon4@tests.mozilla.org",
788 version: "5.0",
789 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
790 targetApplications: [{
791 id: "xpcshell@tests.mozilla.org",
792 minVersion: "0",
793 maxVersion: "1"
794 }],
795 name: "Test Addon 1",
796 }, profileDir);
798 restartManager();
800 AddonManager.getAddonByID("addon4@tests.mozilla.org", function(a4) {
801 do_check_true(a4.isActive);
802 do_check_true(a4.isCompatible);
804 run_test_10();
805 });
806 }
808 // Tests that a normal update check won't decrease a targetApplication's
809 // maxVersion.
810 function run_test_10() {
811 AddonManager.getAddonByID("addon4@tests.mozilla.org", function(a4) {
812 a4.findUpdates({
813 onUpdateFinished: function(addon) {
814 do_check_true(addon.isCompatible);
816 run_test_11();
817 }
818 }, AddonManager.UPDATE_WHEN_PERIODIC_UPDATE);
819 });
820 }
822 // Tests that an update check for a new application will decrease a
823 // targetApplication's maxVersion.
824 function run_test_11() {
825 AddonManager.getAddonByID("addon4@tests.mozilla.org", function(a4) {
826 a4.findUpdates({
827 onUpdateFinished: function(addon) {
828 do_check_true(addon.isCompatible);
830 do_execute_soon(run_test_12);
831 }
832 }, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED);
833 });
834 }
836 // Check that the decreased maxVersion applied and disables the add-on
837 function run_test_12() {
838 restartManager();
840 AddonManager.getAddonByID("addon4@tests.mozilla.org", function(a4) {
841 do_check_true(a4.isActive);
842 do_check_true(a4.isCompatible);
844 a4.uninstall();
845 do_execute_soon(run_test_13);
846 });
847 }
849 // Tests that a compatibility update is passed to the listener when there is
850 // compatibility info for the current version of the app but not for the
851 // version of the app that the caller requested an update check for, when
852 // strict compatibility checking is disabled.
853 function run_test_13() {
854 restartManager();
856 // Not initially compatible but the update check will make it compatible
857 writeInstallRDFForExtension({
858 id: "addon7@tests.mozilla.org",
859 version: "1.0",
860 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
861 targetApplications: [{
862 id: "xpcshell@tests.mozilla.org",
863 minVersion: "0",
864 maxVersion: "0"
865 }],
866 name: "Test Addon 7",
867 }, profileDir);
868 restartManager();
870 AddonManager.getAddonByID("addon7@tests.mozilla.org", function(a7) {
871 do_check_neq(a7, null);
872 do_check_true(a7.isActive);
873 do_check_true(a7.isCompatible);
874 do_check_false(a7.appDisabled);
875 do_check_true(a7.isCompatibleWith("0"));
877 a7.findUpdates({
878 sawUpdate: false,
879 onNoCompatibilityUpdateAvailable: function(addon) {
880 do_throw("Should have seen compatibility information");
881 },
883 onUpdateAvailable: function(addon, install) {
884 do_throw("Should not have seen an available update");
885 },
887 onUpdateFinished: function(addon) {
888 do_check_true(addon.isCompatible);
889 do_execute_soon(check_test_13);
890 }
891 }, AddonManager.UPDATE_WHEN_NEW_APP_DETECTED, "3.0");
892 });
893 }
895 function check_test_13() {
896 restartManager();
897 AddonManager.getAddonByID("addon7@tests.mozilla.org", function(a7) {
898 do_check_neq(a7, null);
899 do_check_true(a7.isActive);
900 do_check_true(a7.isCompatible);
901 do_check_false(a7.appDisabled);
903 a7.uninstall();
904 do_execute_soon(run_test_14);
905 });
906 }
908 // Test that background update checks doesn't update an add-on that isn't
909 // allowed to update automatically.
910 function run_test_14() {
911 restartManager();
913 // Have an add-on there that will be updated so we see some events from it
914 writeInstallRDFForExtension({
915 id: "addon1@tests.mozilla.org",
916 version: "1.0",
917 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
918 targetApplications: [{
919 id: "xpcshell@tests.mozilla.org",
920 minVersion: "1",
921 maxVersion: "1"
922 }],
923 name: "Test Addon 1",
924 }, profileDir);
926 writeInstallRDFForExtension({
927 id: "addon8@tests.mozilla.org",
928 version: "1.0",
929 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
930 targetApplications: [{
931 id: "xpcshell@tests.mozilla.org",
932 minVersion: "1",
933 maxVersion: "1"
934 }],
935 name: "Test Addon 8",
936 }, profileDir);
937 restartManager();
939 AddonManager.getAddonByID("addon8@tests.mozilla.org", function(a8) {
940 a8.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DISABLE;
942 // The background update check will find updates for both add-ons but only
943 // proceed to install one of them.
944 AddonManager.addInstallListener({
945 onNewInstall: function(aInstall) {
946 if (aInstall.existingAddon.id != "addon1@tests.mozilla.org" &&
947 aInstall.existingAddon.id != "addon8@tests.mozilla.org")
948 do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
949 },
951 onDownloadStarted: function(aInstall) {
952 do_check_eq(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
953 },
955 onDownloadEnded: function(aInstall) {
956 do_check_eq(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
957 },
959 onDownloadFailed: function(aInstall) {
960 do_throw("Should not have seen onDownloadFailed event");
961 },
963 onDownloadCancelled: function(aInstall) {
964 do_throw("Should not have seen onDownloadCancelled event");
965 },
967 onInstallStarted: function(aInstall) {
968 do_check_eq(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
969 },
971 onInstallEnded: function(aInstall) {
972 do_check_eq(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
973 do_check_eq(aInstall.existingAddon.pendingUpgrade.install, aInstall);
975 do_execute_soon(check_test_14);
976 },
978 onInstallFailed: function(aInstall) {
979 do_throw("Should not have seen onInstallFailed event");
980 },
982 onInstallCancelled: function(aInstall) {
983 do_throw("Should not have seen onInstallCancelled event");
984 },
985 });
987 // Fake a timer event
988 gInternalManager.notify(null);
989 });
990 }
992 function check_test_14() {
993 restartManager();
994 AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
995 "addon8@tests.mozilla.org"], function([a1, a8]) {
996 do_check_neq(a1, null);
997 do_check_eq(a1.version, "2.0");
998 a1.uninstall();
1000 do_check_neq(a8, null);
1001 do_check_eq(a8.version, "1.0");
1002 a8.uninstall();
1004 do_execute_soon(run_test_15);
1005 });
1006 }
1008 // Test that background update checks doesn't update an add-on that is
1009 // pending uninstall
1010 function run_test_15() {
1011 restartManager();
1013 // Have an add-on there that will be updated so we see some events from it
1014 writeInstallRDFForExtension({
1015 id: "addon1@tests.mozilla.org",
1016 version: "1.0",
1017 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
1018 targetApplications: [{
1019 id: "xpcshell@tests.mozilla.org",
1020 minVersion: "1",
1021 maxVersion: "1"
1022 }],
1023 name: "Test Addon 1",
1024 }, profileDir);
1026 writeInstallRDFForExtension({
1027 id: "addon8@tests.mozilla.org",
1028 version: "1.0",
1029 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
1030 targetApplications: [{
1031 id: "xpcshell@tests.mozilla.org",
1032 minVersion: "1",
1033 maxVersion: "1"
1034 }],
1035 name: "Test Addon 8",
1036 }, profileDir);
1037 restartManager();
1039 AddonManager.getAddonByID("addon8@tests.mozilla.org", function(a8) {
1040 a8.uninstall();
1041 do_check_false(hasFlag(a8.permissions, AddonManager.PERM_CAN_UPGRADE));
1043 // The background update check will find updates for both add-ons but only
1044 // proceed to install one of them.
1045 AddonManager.addInstallListener({
1046 onNewInstall: function(aInstall) {
1047 if (aInstall.existingAddon.id != "addon1@tests.mozilla.org" &&
1048 aInstall.existingAddon.id != "addon8@tests.mozilla.org")
1049 do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
1050 },
1052 onDownloadStarted: function(aInstall) {
1053 do_check_eq(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
1054 },
1056 onDownloadEnded: function(aInstall) {
1057 do_check_eq(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
1058 },
1060 onDownloadFailed: function(aInstall) {
1061 do_throw("Should not have seen onDownloadFailed event");
1062 },
1064 onDownloadCancelled: function(aInstall) {
1065 do_throw("Should not have seen onDownloadCancelled event");
1066 },
1068 onInstallStarted: function(aInstall) {
1069 do_check_eq(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
1070 },
1072 onInstallEnded: function(aInstall) {
1073 do_check_eq(aInstall.existingAddon.id, "addon1@tests.mozilla.org");
1074 do_execute_soon(check_test_15);
1075 },
1077 onInstallFailed: function(aInstall) {
1078 do_throw("Should not have seen onInstallFailed event");
1079 },
1081 onInstallCancelled: function(aInstall) {
1082 do_throw("Should not have seen onInstallCancelled event");
1083 },
1084 });
1086 // Fake a timer event
1087 gInternalManager.notify(null);
1088 });
1089 }
1091 function check_test_15() {
1092 restartManager();
1093 AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
1094 "addon8@tests.mozilla.org"], function([a1, a8]) {
1095 do_check_neq(a1, null);
1096 do_check_eq(a1.version, "2.0");
1097 a1.uninstall();
1099 do_check_eq(a8, null);
1101 do_execute_soon(run_test_16);
1102 });
1103 }
1105 function run_test_16() {
1106 restartManager();
1108 restartManager();
1110 let url = "http://localhost:" + gPort + "/addons/test_install2_1.xpi";
1111 AddonManager.getInstallForURL(url, function(aInstall) {
1112 aInstall.addListener({
1113 onInstallEnded: function() {
1114 do_execute_soon(function install_2_1_ended() {
1115 restartManager();
1117 AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a1) {
1118 do_check_neq(a1.syncGUID, null);
1119 let oldGUID = a1.syncGUID;
1121 let url = "http://localhost:" + gPort + "/addons/test_install2_2.xpi";
1122 AddonManager.getInstallForURL(url, function(aInstall) {
1123 aInstall.addListener({
1124 onInstallEnded: function() {
1125 do_execute_soon(function install_2_2_ended() {
1126 restartManager();
1128 AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
1129 do_check_neq(a2.syncGUID, null);
1130 do_check_eq(oldGUID, a2.syncGUID);
1132 a2.uninstall();
1133 do_execute_soon(run_test_17);
1134 });
1135 });
1136 }
1137 });
1138 aInstall.install();
1139 }, "application/x-xpinstall");
1140 });
1141 });
1142 }
1143 });
1144 aInstall.install();
1145 }, "application/x-xpinstall");
1146 }
1148 // Test that the update check correctly observes the
1149 // extensions.strictCompatibility pref and compatibility overrides.
1150 function run_test_17() {
1151 restartManager();
1153 writeInstallRDFForExtension({
1154 id: "addon9@tests.mozilla.org",
1155 version: "1.0",
1156 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
1157 targetApplications: [{
1158 id: "xpcshell@tests.mozilla.org",
1159 minVersion: "0.1",
1160 maxVersion: "0.2"
1161 }],
1162 name: "Test Addon 9",
1163 }, profileDir);
1164 restartManager();
1166 AddonManager.addInstallListener({
1167 onNewInstall: function(aInstall) {
1168 if (aInstall.existingAddon.id != "addon9@tests.mozilla.org")
1169 do_throw("Saw unexpected onNewInstall for " + aInstall.existingAddon.id);
1170 do_check_eq(aInstall.version, "3.0");
1171 },
1172 onDownloadFailed: function(aInstall) {
1173 AddonManager.getAddonByID("addon9@tests.mozilla.org", function(a9) {
1174 a9.uninstall();
1175 do_execute_soon(run_test_18);
1176 });
1177 }
1178 });
1180 Services.prefs.setCharPref(PREF_GETADDONS_BYIDS,
1181 "http://localhost:" + gPort + "/data/test_update.xml");
1182 Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE,
1183 "http://localhost:" + gPort + "/data/test_update.xml");
1184 Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
1185 // Fake a timer event
1186 gInternalManager.notify(null);
1187 }
1189 // Tests that compatibility updates are applied to addons when the updated
1190 // compatibility data wouldn't match with strict compatibility enabled.
1191 function run_test_18() {
1192 restartManager();
1193 writeInstallRDFForExtension({
1194 id: "addon10@tests.mozilla.org",
1195 version: "1.0",
1196 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
1197 targetApplications: [{
1198 id: "xpcshell@tests.mozilla.org",
1199 minVersion: "0.1",
1200 maxVersion: "0.2"
1201 }],
1202 name: "Test Addon 10",
1203 }, profileDir);
1204 restartManager();
1206 AddonManager.getAddonByID("addon10@tests.mozilla.org", function(a10) {
1207 do_check_neq(a10, null);
1209 a10.findUpdates({
1210 onNoCompatibilityUpdateAvailable: function() {
1211 do_throw("Should have seen compatibility information");
1212 },
1214 onUpdateAvailable: function() {
1215 do_throw("Should not have seen an available update");
1216 },
1218 onUpdateFinished: function() {
1219 a10.uninstall();
1220 do_execute_soon(run_test_19);
1221 }
1222 }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
1223 });
1224 }
1226 // Test that the update check correctly observes when an addon opts-in to
1227 // strict compatibility checking.
1228 function run_test_19() {
1229 restartManager();
1230 writeInstallRDFForExtension({
1231 id: "addon11@tests.mozilla.org",
1232 version: "1.0",
1233 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
1234 targetApplications: [{
1235 id: "xpcshell@tests.mozilla.org",
1236 minVersion: "0.1",
1237 maxVersion: "0.2"
1238 }],
1239 name: "Test Addon 11",
1240 }, profileDir);
1241 restartManager();
1243 AddonManager.getAddonByID("addon11@tests.mozilla.org", function(a11) {
1244 do_check_neq(a11, null);
1246 a11.findUpdates({
1247 onCompatibilityUpdateAvailable: function() {
1248 do_throw("Should have not have seen compatibility information");
1249 },
1251 onUpdateAvailable: function() {
1252 do_throw("Should not have seen an available update");
1253 },
1255 onUpdateFinished: function() {
1256 a11.uninstall();
1257 do_execute_soon(run_test_20);
1258 }
1259 }, AddonManager.UPDATE_WHEN_USER_REQUESTED);
1260 });
1261 }
1263 // Test that the update succeeds when the update.rdf URN contains a type prefix
1264 // different from the add-on type
1265 function run_test_20() {
1266 restartManager();
1267 writeInstallRDFForExtension({
1268 id: "addon12@tests.mozilla.org",
1269 version: "1.0",
1270 updateURL: "http://localhost:" + gPort + "/data/test_update.rdf",
1271 targetApplications: [{
1272 id: "xpcshell@tests.mozilla.org",
1273 minVersion: "1",
1274 maxVersion: "1"
1275 }],
1276 name: "Test Addon 12",
1277 }, profileDir);
1278 restartManager();
1280 prepare_test({}, [
1281 "onNewInstall",
1282 "onDownloadStarted",
1283 "onDownloadEnded"
1284 ], continue_test_20);
1286 AddonManagerPrivate.backgroundUpdateCheck();
1287 }
1289 function continue_test_20(install) {
1290 do_check_neq(install.existingAddon, null);
1291 do_check_eq(install.existingAddon.id, "addon12@tests.mozilla.org");
1293 prepare_test({
1294 "addon12@tests.mozilla.org": [
1295 "onInstalling"
1296 ]
1297 }, [
1298 "onInstallStarted",
1299 "onInstallEnded",
1300 ], callback_soon(check_test_20));
1301 }
1303 function check_test_20(install) {
1304 do_check_eq(install.existingAddon.pendingUpgrade.install, install);
1306 restartManager();
1307 AddonManager.getAddonByID("addon12@tests.mozilla.org", function(a12) {
1308 do_check_neq(a12, null);
1309 do_check_eq(a12.version, "2.0");
1310 do_check_eq(a12.type, "extension");
1311 a12.uninstall();
1313 do_execute_soon(() => {
1314 restartManager();
1315 end_test();
1316 });
1317 });
1318 }