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 // Tests AddonRepository.jsm
7 Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm");
9 Components.utils.import("resource://testing-common/httpd.js");
10 var gServer = new HttpServer();
11 gServer.start(-1);
13 const PREF_GETADDONS_BROWSEADDONS = "extensions.getAddons.browseAddons";
14 const PREF_GETADDONS_BROWSERECOMMENDED = "extensions.getAddons.recommended.browseURL";
15 const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url";
16 const PREF_GETADDONS_BROWSESEARCHRESULTS = "extensions.getAddons.search.browseURL";
17 const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url";
19 const PORT = gServer.identity.primaryPort;
20 const BASE_URL = "http://localhost:" + PORT;
21 const DEFAULT_URL = "about:blank";
23 gPort = PORT;
25 // Path to source URI of installed add-on
26 const INSTALL_URL1 = "/addons/test_AddonRepository_1.xpi";
27 // Path to source URI of installing add-on
28 const INSTALL_URL2 = "/addons/test_AddonRepository_2.xpi";
29 // Path to source URI of non-active add-on (state = STATE_AVAILABLE)
30 const INSTALL_URL3 = "/addons/test_AddonRepository_3.xpi";
32 // Properties of an individual add-on that should be checked
33 // Note: name is checked separately
34 var ADDON_PROPERTIES = ["id", "type", "version", "creator", "developers",
35 "description", "fullDescription", "developerComments",
36 "eula", "iconURL", "icons", "screenshots", "homepageURL",
37 "supportURL", "contributionURL", "contributionAmount",
38 "averageRating", "reviewCount", "reviewURL",
39 "totalDownloads", "weeklyDownloads", "dailyUsers",
40 "sourceURI", "repositoryStatus", "size", "updateDate",
41 "purchaseURL", "purchaseAmount", "purchaseDisplayAmount",
42 "compatibilityOverrides"];
44 // Results of getAddonsByIDs
45 var GET_RESULTS = [{
46 id: "test1@tests.mozilla.org",
47 type: "extension",
48 version: "1.1",
49 creator: {
50 name: "Test Creator 1",
51 url: BASE_URL + "/creator1.html"
52 },
53 developers: [{
54 name: "Test Developer 1",
55 url: BASE_URL + "/developer1.html"
56 }],
57 description: "Test Summary 1",
58 fullDescription: "Test Description 1",
59 developerComments: "Test Developer Comments 1",
60 eula: "Test EULA 1",
61 iconURL: BASE_URL + "/icon1.png",
62 icons: { "32": BASE_URL + "/icon1.png" },
63 screenshots: [{
64 url: BASE_URL + "/full1-1.png",
65 width: 400,
66 height: 300,
67 thumbnailURL: BASE_URL + "/thumbnail1-1.png",
68 thumbnailWidth: 200,
69 thumbnailHeight: 150,
70 caption: "Caption 1 - 1"
71 }, {
72 url: BASE_URL + "/full2-1.png",
73 thumbnailURL: BASE_URL + "/thumbnail2-1.png",
74 caption: "Caption 2 - 1"
75 }],
76 homepageURL: BASE_URL + "/learnmore1.html",
77 learnmoreURL: BASE_URL + "/learnmore1.html",
78 supportURL: BASE_URL + "/support1.html",
79 contributionURL: BASE_URL + "/meetDevelopers1.html",
80 contributionAmount: "$11.11",
81 averageRating: 4,
82 reviewCount: 1111,
83 reviewURL: BASE_URL + "/review1.html",
84 totalDownloads: 2222,
85 weeklyDownloads: 3333,
86 dailyUsers: 4444,
87 sourceURI: BASE_URL + INSTALL_URL2,
88 repositoryStatus: 8,
89 size: 5555,
90 updateDate: new Date(1265033045000),
91 compatibilityOverrides: [{
92 type: "incompatible",
93 minVersion: 0.1,
94 maxVersion: 0.2,
95 appID: "xpcshell@tests.mozilla.org",
96 appMinVersion: 3.0,
97 appMaxVersion: 4.0
98 }, {
99 type: "incompatible",
100 minVersion: 0.2,
101 maxVersion: 0.3,
102 appID: "xpcshell@tests.mozilla.org",
103 appMinVersion: 5.0,
104 appMaxVersion: 6.0
105 }]
106 }, {
107 id: "test_AddonRepository_1@tests.mozilla.org",
108 version: "1.4",
109 repositoryStatus: 9999,
110 icons: {}
111 }];
113 // Results of retrieveRecommendedAddons and searchAddons
114 var SEARCH_RESULTS = [{
115 id: "test1@tests.mozilla.org",
116 type: "extension",
117 version: "1.1",
118 creator: {
119 name: "Test Creator 1",
120 url: BASE_URL + "/creator1.html"
121 },
122 repositoryStatus: 8,
123 sourceURI: BASE_URL + "/test1.xpi",
124 icons: {}
125 }, {
126 id: "test2@tests.mozilla.org",
127 type: "extension",
128 version: "1.2",
129 creator: {
130 name: "Test Creator 2",
131 url: BASE_URL + "/creator2.html"
132 },
133 developers: [{
134 name: "Test Developer 2",
135 url: BASE_URL + "/developer2.html"
136 }],
137 description: "Test Summary 2\n\nparagraph",
138 fullDescription: "Test Description 2\nnewline",
139 developerComments: "Test Developer\nComments 2",
140 eula: "Test EULA 2",
141 iconURL: BASE_URL + "/icon2-32.png",
142 icons: {
143 "32": BASE_URL + "/icon2-32.png",
144 "48": BASE_URL + "/icon2-48.png",
145 "64": BASE_URL + "/icon2-64.png"
146 },
147 screenshots: [{
148 url: BASE_URL + "/full1-2.png",
149 thumbnailURL: BASE_URL + "/thumbnail1-2.png"
150 }, {
151 url: BASE_URL + "/full2-2.png",
152 thumbnailURL: BASE_URL + "/thumbnail2-2.png",
153 caption: "Caption 2"
154 }],
155 homepageURL: BASE_URL + "/learnmore2.html",
156 supportURL: BASE_URL + "/support2.html",
157 learnmoreURL: BASE_URL + "/learnmore2.html",
158 contributionURL: BASE_URL + "/meetDevelopers2.html",
159 contributionAmount: null,
160 repositoryStatus: 4,
161 sourceURI: BASE_URL + "/test2.xpi"
162 }, {
163 id: "test3@tests.mozilla.org",
164 type: "theme",
165 version: "1.3",
166 creator: {
167 name: "Test Creator 3",
168 url: BASE_URL + "/creator3.html"
169 },
170 developers: [{
171 name: "First Test Developer 3",
172 url: BASE_URL + "/developer1-3.html"
173 }, {
174 name: "Second Test Developer 3",
175 url: BASE_URL + "/developer2-3.html"
176 }],
177 description: "Test Summary 3",
178 fullDescription: "Test Description 3\n\n List item 1\n List item 2",
179 developerComments: "Test Developer Comments 3",
180 eula: "Test EULA 3",
181 iconURL: BASE_URL + "/icon3.png",
182 icons: { "32": BASE_URL + "/icon3.png" },
183 screenshots: [{
184 url: BASE_URL + "/full1-3.png",
185 thumbnailURL: BASE_URL + "/thumbnail1-3.png",
186 caption: "Caption 1 - 3"
187 }, {
188 url: BASE_URL + "/full2-3.png",
189 caption: "Caption 2 - 3"
190 }, {
191 url: BASE_URL + "/full3-3.png",
192 thumbnailURL: BASE_URL + "/thumbnail3-3.png",
193 caption: "Caption 3 - 3"
194 }],
195 homepageURL: BASE_URL + "/homepage3.html",
196 supportURL: BASE_URL + "/support3.html",
197 learnmoreURL: BASE_URL + "/learnmore3.html",
198 contributionURL: BASE_URL + "/meetDevelopers3.html",
199 contributionAmount: "$11.11",
200 averageRating: 2,
201 reviewCount: 1111,
202 reviewURL: BASE_URL + "/review3.html",
203 totalDownloads: 2222,
204 weeklyDownloads: 3333,
205 dailyUsers: 4444,
206 sourceURI: BASE_URL + "/test3.xpi",
207 repositoryStatus: 8,
208 size: 5555,
209 updateDate: new Date(1265033045000),
211 }, {
212 id: "purchase1@tests.mozilla.org",
213 type: "extension",
214 version: "2.0",
215 creator: {
216 name: "Test Creator - Last Passing",
217 url: BASE_URL + "/creatorLastPassing.html"
218 },
219 averageRating: 5,
220 repositoryStatus: 4,
221 purchaseURL: "http://localhost:" + PORT + "/purchaseURL1",
222 purchaseAmount: 5,
223 purchaseDisplayAmount: "$5",
224 icons: {}
225 }, {
226 id: "purchase2@tests.mozilla.org",
227 type: "extension",
228 version: "2.0",
229 creator: {
230 name: "Test Creator - Last Passing",
231 url: BASE_URL + "/creatorLastPassing.html"
232 },
233 averageRating: 5,
234 repositoryStatus: 4,
235 purchaseURL: "http://localhost:" + PORT + "/purchaseURL2",
236 purchaseAmount: 10,
237 purchaseDisplayAmount: "$10",
238 icons: {}
239 }, {
240 id: "test-lastPassing@tests.mozilla.org",
241 type: "extension",
242 version: "2.0",
243 creator: {
244 name: "Test Creator - Last Passing",
245 url: BASE_URL + "/creatorLastPassing.html"
246 },
247 averageRating: 5,
248 repositoryStatus: 4,
249 sourceURI: BASE_URL + "/addons/test_AddonRepository_3.xpi",
250 icons: {}
251 }];
253 const TOTAL_RESULTS = 1111;
254 const MAX_RESULTS = SEARCH_RESULTS.length;
256 // Used to differentiate between testing that a search success
257 // or a search failure for retrieveRecommendedAddons and searchAddons
258 const FAILED_MAX_RESULTS = 9999;
260 // Values for testing AddonRepository.getAddonsByIDs()
261 var GET_TEST = {
262 preference: PREF_GETADDONS_BYIDS,
263 preferenceValue: BASE_URL + "/%OS%/%VERSION%/%API_VERSION%/" +
264 "%API_VERSION%/%IDS%",
265 failedIDs: ["test1@tests.mozilla.org"],
266 failedURL: "/XPCShell/1/1.5/1.5/test1%40tests.mozilla.org",
267 successfulIDs: ["test1@tests.mozilla.org",
268 "{00000000-1111-2222-3333-444444444444}",
269 "test_AddonRepository_1@tests.mozilla.org"],
270 successfulURL: "/XPCShell/1/1.5/1.5/test1%40tests.mozilla.org," +
271 "%7B00000000-1111-2222-3333-444444444444%7D," +
272 "test_AddonRepository_1%40tests.mozilla.org"
273 };
275 // Values for testing AddonRepository.retrieveRecommendedAddons()
276 var RECOMMENDED_TEST = {
277 preference: PREF_GETADDONS_GETRECOMMENDED,
278 preferenceValue: BASE_URL + "/%OS%/%VERSION%/%API_VERSION%/" +
279 "%API_VERSION%/%MAX_RESULTS%",
280 failedURL: "/XPCShell/1/1.5/1.5/" + (2 * FAILED_MAX_RESULTS),
281 successfulURL: "/XPCShell/1/1.5/1.5/" + (2 * MAX_RESULTS)
282 };
284 // Values for testing AddonRepository.searchAddons()
285 var SEARCH_TEST = {
286 searchTerms: "odd=search:with&weird\"characters",
287 preference: PREF_GETADDONS_GETSEARCHRESULTS,
288 preferenceValue: BASE_URL + "/%OS%/%VERSION%/%API_VERSION%/" +
289 "%API_VERSION%/%MAX_RESULTS%/%TERMS%",
290 failedURL: "/XPCShell/1/1.5/1.5/" + (2 * FAILED_MAX_RESULTS) +
291 "/odd%3Dsearch%3Awith%26weird%22characters",
292 successfulURL: "/XPCShell/1/1.5/1.5/" + (2 * MAX_RESULTS) +
293 "/odd%3Dsearch%3Awith%26weird%22characters"
294 };
296 // Test that actual results and expected results are equal
297 function check_results(aActualAddons, aExpectedAddons, aAddonCount, aInstallNull) {
298 do_check_false(AddonRepository.isSearching);
300 do_check_eq(aActualAddons.length, aAddonCount);
301 do_check_addons(aActualAddons, aExpectedAddons, ADDON_PROPERTIES);
303 // Additional tests
304 aActualAddons.forEach(function check_each_addon(aActualAddon) {
305 // Separately check name so better messages are output when test fails
306 if (aActualAddon.name == "FAIL")
307 do_throw(aActualAddon.id + " - " + aActualAddon.description);
308 if (aActualAddon.name != "PASS")
309 do_throw(aActualAddon.id + " - " + "invalid add-on name " + aActualAddon.name);
311 do_check_eq(aActualAddon.install == null, !!aInstallNull || !aActualAddon.sourceURI);
313 // Check that sourceURI property consistent within actual addon
314 if (aActualAddon.install)
315 do_check_eq(aActualAddon.install.sourceURI.spec, aActualAddon.sourceURI.spec);
316 });
317 }
319 // Complete a search, also testing cancelSearch() and isSearching
320 function complete_search(aSearch, aSearchCallback) {
321 var failCallback = {
322 searchSucceeded: function(addons, length, total) {
323 do_throw("failCallback.searchSucceeded should not be called");
324 end_test();
325 },
327 searchFailed: function() {
328 do_throw("failCallback.searchFailed should not be called");
329 end_test();
330 }
331 };
333 var callbackCalled = false;
334 var testCallback = {
335 searchSucceeded: function(addons, length, total) {
336 do_throw("testCallback.searchSucceeded should not be called");
337 end_test();
338 },
340 searchFailed: function() {
341 callbackCalled = true;
342 }
343 };
345 // Should fail because cancelled it immediately
346 aSearch(failCallback);
347 do_check_true(AddonRepository.isSearching);
348 AddonRepository.cancelSearch();
349 do_check_false(AddonRepository.isSearching);
351 aSearch(aSearchCallback);
352 do_check_true(AddonRepository.isSearching);
354 // searchFailed should be called immediately because already searching
355 aSearch(testCallback);
356 do_check_true(callbackCalled);
357 do_check_true(AddonRepository.isSearching);
358 }
361 function run_test() {
362 // Setup for test
363 do_test_pending();
364 createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
366 startupManager();
368 // Install an add-on so can check that it isn't returned in the results
369 installAllFiles([do_get_addon("test_AddonRepository_1")], function addon_1_install_callback() {
370 restartManager();
372 // Register other add-on XPI files
373 gServer.registerFile(INSTALL_URL2,
374 do_get_addon("test_AddonRepository_2"));
375 gServer.registerFile(INSTALL_URL3,
376 do_get_addon("test_AddonRepository_3"));
378 // Register files used to test search failure
379 mapUrlToFile(GET_TEST.failedURL,
380 do_get_file("data/test_AddonRepository_failed.xml"),
381 gServer);
382 mapUrlToFile(RECOMMENDED_TEST.failedURL,
383 do_get_file("data/test_AddonRepository_failed.xml"),
384 gServer);
385 mapUrlToFile(SEARCH_TEST.failedURL,
386 do_get_file("data/test_AddonRepository_failed.xml"),
387 gServer);
389 // Register files used to test search success
390 mapUrlToFile(GET_TEST.successfulURL,
391 do_get_file("data/test_AddonRepository_getAddonsByIDs.xml"),
392 gServer);
393 mapUrlToFile(RECOMMENDED_TEST.successfulURL,
394 do_get_file("data/test_AddonRepository.xml"),
395 gServer);
396 mapUrlToFile(SEARCH_TEST.successfulURL,
397 do_get_file("data/test_AddonRepository.xml"),
398 gServer);
400 // Create an active AddonInstall so can check that it isn't returned in the results
401 AddonManager.getInstallForURL(BASE_URL + INSTALL_URL2, function addon_2_get(aInstall) {
402 try {
403 aInstall.install();
404 }
405 catch(e) {
406 do_print("Failed to install add-on " + aInstall.sourceURI.spec);
407 do_report_unexpected_exception(e);
408 }
410 // Create a non-active AddonInstall so can check that it is returned in the results
411 AddonManager.getInstallForURL(BASE_URL + INSTALL_URL3,
412 run_test_1, "application/x-xpinstall");
413 }, "application/x-xpinstall");
414 });
415 }
417 function end_test() {
418 let testDir = gProfD.clone();
419 testDir.append("extensions");
420 testDir.append("staged");
421 gServer.stop(function() {
422 function loop() {
423 if (!testDir.exists()) {
424 do_print("Staged directory has been cleaned up");
425 do_test_finished();
426 }
427 do_print("Waiting 1 second until cleanup is complete");
428 do_timeout(1000, loop);
429 }
430 loop();
431 });
432 }
434 // Tests homepageURL, getRecommendedURL() and getSearchURL()
435 function run_test_1() {
436 function check_urls(aPreference, aGetURL, aTests) {
437 aTests.forEach(function(aTest) {
438 Services.prefs.setCharPref(aPreference, aTest.preferenceValue);
439 do_check_eq(aGetURL(aTest), aTest.expectedURL);
440 });
441 }
443 var urlTests = [{
444 preferenceValue: BASE_URL,
445 expectedURL: BASE_URL
446 }, {
447 preferenceValue: BASE_URL + "/%OS%/%VERSION%",
448 expectedURL: BASE_URL + "/XPCShell/1"
449 }];
451 // Extra tests for AddonRepository.getSearchURL();
452 var searchURLTests = [{
453 searchTerms: "test",
454 preferenceValue: BASE_URL + "/search?q=%TERMS%",
455 expectedURL: BASE_URL + "/search?q=test"
456 }, {
457 searchTerms: "test search",
458 preferenceValue: BASE_URL + "/%TERMS%",
459 expectedURL: BASE_URL + "/test%20search"
460 }, {
461 searchTerms: "odd=search:with&weird\"characters",
462 preferenceValue: BASE_URL + "/%TERMS%",
463 expectedURL: BASE_URL + "/odd%3Dsearch%3Awith%26weird%22characters"
464 }];
466 // Setup tests for homepageURL, getRecommendedURL() and getSearchURL()
467 var tests = [{
468 initiallyUndefined: true,
469 preference: PREF_GETADDONS_BROWSEADDONS,
470 urlTests: urlTests,
471 getURL: function() AddonRepository.homepageURL
472 }, {
473 initiallyUndefined: true,
474 preference: PREF_GETADDONS_BROWSERECOMMENDED,
475 urlTests: urlTests,
476 getURL: function() AddonRepository.getRecommendedURL()
477 }, {
478 initiallyUndefined: false,
479 preference: PREF_GETADDONS_BROWSESEARCHRESULTS,
480 urlTests: urlTests.concat(searchURLTests),
481 getURL: function getSearchURL(aTest) {
482 var searchTerms = aTest && aTest.searchTerms ? aTest.searchTerms
483 : "unused terms";
484 return AddonRepository.getSearchURL(searchTerms);
485 }
486 }];
488 tests.forEach(function url_test(aTest) {
489 if (aTest.initiallyUndefined) {
490 // Preference is not defined by default
491 do_check_eq(Services.prefs.getPrefType(aTest.preference),
492 Services.prefs.PREF_INVALID);
493 do_check_eq(aTest.getURL(), DEFAULT_URL);
494 }
496 check_urls(aTest.preference, aTest.getURL, aTest.urlTests);
497 });
499 run_test_getAddonsByID_fails();
500 }
502 // Tests failure of AddonRepository.getAddonsByIDs()
503 function run_test_getAddonsByID_fails() {
504 Services.prefs.setCharPref(GET_TEST.preference, GET_TEST.preferenceValue);
505 var callback = {
506 searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) {
507 do_throw("searchAddons should not have succeeded");
508 end_test();
509 },
511 searchFailed: function() {
512 do_check_false(AddonRepository.isSearching);
513 run_test_getAddonsByID_succeeds();
514 }
515 };
517 complete_search(function complete_search_fail_callback(aCallback) {
518 AddonRepository.getAddonsByIDs(GET_TEST.failedIDs, aCallback);
519 }, callback);
520 }
522 // Tests success of AddonRepository.getAddonsByIDs()
523 function run_test_getAddonsByID_succeeds() {
524 var callback = {
525 searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) {
526 do_check_eq(aTotalResults, -1);
527 check_results(aAddonsList, GET_RESULTS, aAddonCount, true);
528 run_test_retrieveRecommended_fails();
529 },
531 searchFailed: function() {
532 do_throw("searchAddons should not have failed");
533 end_test();
534 }
535 };
537 complete_search(function complete_search_succeed_callback(aCallback) {
538 AddonRepository.getAddonsByIDs(GET_TEST.successfulIDs, aCallback);
539 }, callback);
540 }
542 // Tests failure of AddonRepository.retrieveRecommendedAddons()
543 function run_test_retrieveRecommended_fails() {
544 Services.prefs.setCharPref(RECOMMENDED_TEST.preference,
545 RECOMMENDED_TEST.preferenceValue);
546 var callback = {
547 searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) {
548 do_throw("retrieveRecommendedAddons should not have succeeded");
549 end_test();
550 },
552 searchFailed: function() {
553 do_check_false(AddonRepository.isSearching);
554 run_test_retrieveRecommended_succeed();
555 }
556 };
558 complete_search(function retrieveRecommended_failing_callback(aCallback) {
559 AddonRepository.retrieveRecommendedAddons(FAILED_MAX_RESULTS, aCallback);
560 }, callback);
561 }
563 // Tests success of AddonRepository.retrieveRecommendedAddons()
564 function run_test_retrieveRecommended_succeed() {
565 var callback = {
566 searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) {
567 do_check_eq(aTotalResults, -1);
568 check_results(aAddonsList, SEARCH_RESULTS, aAddonCount);
569 run_test_searchAddons_fails();
570 },
572 searchFailed: function() {
573 do_throw("retrieveRecommendedAddons should not have failed");
574 end_test();
575 }
576 };
578 complete_search(function retrieveRecommended_succeed_callback(aCallback) {
579 AddonRepository.retrieveRecommendedAddons(MAX_RESULTS, aCallback);
580 }, callback);
581 }
583 // Tests failure of AddonRepository.searchAddons()
584 function run_test_searchAddons_fails() {
585 Services.prefs.setCharPref(SEARCH_TEST.preference, SEARCH_TEST.preferenceValue);
586 var callback = {
587 searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) {
588 do_throw("searchAddons should not have succeeded");
589 end_test();
590 },
592 searchFailed: function() {
593 do_check_false(AddonRepository.isSearching);
594 run_test_searchAddons_succeeds();
595 }
596 };
598 complete_search(function(aCallback) {
599 var searchTerms = SEARCH_TEST.searchTerms;
600 AddonRepository.searchAddons(searchTerms, FAILED_MAX_RESULTS, aCallback);
601 }, callback);
602 }
604 // Tests success of AddonRepository.searchAddons()
605 function run_test_searchAddons_succeeds() {
606 var callback = {
607 searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) {
608 do_check_eq(aTotalResults, TOTAL_RESULTS);
609 check_results(aAddonsList, SEARCH_RESULTS, aAddonCount);
610 end_test();
611 },
613 searchFailed: function() {
614 do_throw("searchAddons should not have failed");
615 end_test();
616 }
617 };
619 complete_search(function(aCallback) {
620 var searchTerms = SEARCH_TEST.searchTerms;
621 AddonRepository.searchAddons(searchTerms, MAX_RESULTS, aCallback);
622 }, callback);
623 }