From 4fb11cd5966461bccc3ed1599b808237be6b0de9 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Sat, 10 Feb 2018 02:49:12 -0500 Subject: Move WebExtensions enabled Add-ons Manager --- .../test/xpcshell/test_AddonRepository.js | 625 +++++++++++++++++++++ 1 file changed, 625 insertions(+) create mode 100644 toolkit/mozapps/webextensions/test/xpcshell/test_AddonRepository.js (limited to 'toolkit/mozapps/webextensions/test/xpcshell/test_AddonRepository.js') diff --git a/toolkit/mozapps/webextensions/test/xpcshell/test_AddonRepository.js b/toolkit/mozapps/webextensions/test/xpcshell/test_AddonRepository.js new file mode 100644 index 000000000..dd0dc1981 --- /dev/null +++ b/toolkit/mozapps/webextensions/test/xpcshell/test_AddonRepository.js @@ -0,0 +1,625 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Tests AddonRepository.jsm + +Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm"); + +Components.utils.import("resource://testing-common/httpd.js"); +var gServer = new HttpServer(); +gServer.start(-1); + +const PREF_GETADDONS_BROWSEADDONS = "extensions.getAddons.browseAddons"; +const PREF_GETADDONS_BROWSERECOMMENDED = "extensions.getAddons.recommended.browseURL"; +const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url"; +const PREF_GETADDONS_BROWSESEARCHRESULTS = "extensions.getAddons.search.browseURL"; +const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url"; + +const PORT = gServer.identity.primaryPort; +const BASE_URL = "http://localhost:" + PORT; +const DEFAULT_URL = "about:blank"; + +gPort = PORT; + +// Path to source URI of installed add-on +const INSTALL_URL1 = "/addons/test_AddonRepository_1.xpi"; +// Path to source URI of installing add-on +const INSTALL_URL2 = "/addons/test_AddonRepository_2.xpi"; +// Path to source URI of non-active add-on (state = STATE_AVAILABLE) +const INSTALL_URL3 = "/addons/test_AddonRepository_3.xpi"; + +// Properties of an individual add-on that should be checked +// Note: name is checked separately +var ADDON_PROPERTIES = ["id", "type", "version", "creator", "developers", + "description", "fullDescription", "developerComments", + "eula", "iconURL", "icons", "screenshots", "homepageURL", + "supportURL", "contributionURL", "contributionAmount", + "averageRating", "reviewCount", "reviewURL", + "totalDownloads", "weeklyDownloads", "dailyUsers", + "sourceURI", "repositoryStatus", "size", "updateDate", + "purchaseURL", "purchaseAmount", "purchaseDisplayAmount", + "compatibilityOverrides"]; + +// Results of getAddonsByIDs +var GET_RESULTS = [{ + id: "test1@tests.mozilla.org", + type: "extension", + version: "1.1", + creator: { + name: "Test Creator 1", + url: BASE_URL + "/creator1.html" + }, + developers: [{ + name: "Test Developer 1", + url: BASE_URL + "/developer1.html" + }], + description: "Test Summary 1", + fullDescription: "Test Description 1", + developerComments: "Test Developer Comments 1", + eula: "Test EULA 1", + iconURL: BASE_URL + "/icon1.png", + icons: { "32": BASE_URL + "/icon1.png" }, + screenshots: [{ + url: BASE_URL + "/full1-1.png", + width: 400, + height: 300, + thumbnailURL: BASE_URL + "/thumbnail1-1.png", + thumbnailWidth: 200, + thumbnailHeight: 150, + caption: "Caption 1 - 1" + }, { + url: BASE_URL + "/full2-1.png", + thumbnailURL: BASE_URL + "/thumbnail2-1.png", + caption: "Caption 2 - 1" + }], + homepageURL: BASE_URL + "/learnmore1.html", + learnmoreURL: BASE_URL + "/learnmore1.html", + supportURL: BASE_URL + "/support1.html", + contributionURL: BASE_URL + "/meetDevelopers1.html", + contributionAmount: "$11.11", + averageRating: 4, + reviewCount: 1111, + reviewURL: BASE_URL + "/review1.html", + totalDownloads: 2222, + weeklyDownloads: 3333, + dailyUsers: 4444, + sourceURI: BASE_URL + INSTALL_URL2, + repositoryStatus: 8, + size: 5555, + updateDate: new Date(1265033045000), + compatibilityOverrides: [{ + type: "incompatible", + minVersion: 0.1, + maxVersion: 0.2, + appID: "xpcshell@tests.mozilla.org", + appMinVersion: 3.0, + appMaxVersion: 4.0 + }, { + type: "incompatible", + minVersion: 0.2, + maxVersion: 0.3, + appID: "xpcshell@tests.mozilla.org", + appMinVersion: 5.0, + appMaxVersion: 6.0 + }] +}, { + id: "test_AddonRepository_1@tests.mozilla.org", + type: "theme", + version: "1.4", + repositoryStatus: 9999, + icons: {} +}]; + +// Results of retrieveRecommendedAddons and searchAddons +var SEARCH_RESULTS = [{ + id: "test1@tests.mozilla.org", + type: "extension", + version: "1.1", + creator: { + name: "Test Creator 1", + url: BASE_URL + "/creator1.html" + }, + repositoryStatus: 8, + sourceURI: BASE_URL + "/test1.xpi", + icons: {} +}, { + id: "test2@tests.mozilla.org", + type: "extension", + version: "1.2", + creator: { + name: "Test Creator 2", + url: BASE_URL + "/creator2.html" + }, + developers: [{ + name: "Test Developer 2", + url: BASE_URL + "/developer2.html" + }], + description: "Test Summary 2\n\nparagraph", + fullDescription: "Test Description 2\nnewline", + developerComments: "Test Developer\nComments 2", + eula: "Test EULA 2", + iconURL: BASE_URL + "/icon2-32.png", + icons: { + "32": BASE_URL + "/icon2-32.png", + "48": BASE_URL + "/icon2-48.png", + "64": BASE_URL + "/icon2-64.png" + }, + screenshots: [{ + url: BASE_URL + "/full1-2.png", + thumbnailURL: BASE_URL + "/thumbnail1-2.png" + }, { + url: BASE_URL + "/full2-2.png", + thumbnailURL: BASE_URL + "/thumbnail2-2.png", + caption: "Caption 2" + }], + homepageURL: BASE_URL + "/learnmore2.html", + supportURL: BASE_URL + "/support2.html", + learnmoreURL: BASE_URL + "/learnmore2.html", + contributionURL: BASE_URL + "/meetDevelopers2.html", + contributionAmount: null, + repositoryStatus: 4, + sourceURI: BASE_URL + "/test2.xpi" +}, { + id: "test3@tests.mozilla.org", + type: "theme", + version: "1.3", + creator: { + name: "Test Creator 3", + url: BASE_URL + "/creator3.html" + }, + developers: [{ + name: "First Test Developer 3", + url: BASE_URL + "/developer1-3.html" + }, { + name: "Second Test Developer 3", + url: BASE_URL + "/developer2-3.html" + }], + description: "Test Summary 3", + fullDescription: "Test Description 3\n\n List item 1\n List item 2", + developerComments: "Test Developer Comments 3", + eula: "Test EULA 3", + iconURL: BASE_URL + "/icon3.png", + icons: { "32": BASE_URL + "/icon3.png" }, + screenshots: [{ + url: BASE_URL + "/full1-3.png", + thumbnailURL: BASE_URL + "/thumbnail1-3.png", + caption: "Caption 1 - 3" + }, { + url: BASE_URL + "/full2-3.png", + caption: "Caption 2 - 3" + }, { + url: BASE_URL + "/full3-3.png", + thumbnailURL: BASE_URL + "/thumbnail3-3.png", + caption: "Caption 3 - 3" + }], + homepageURL: BASE_URL + "/homepage3.html", + supportURL: BASE_URL + "/support3.html", + learnmoreURL: BASE_URL + "/learnmore3.html", + contributionURL: BASE_URL + "/meetDevelopers3.html", + contributionAmount: "$11.11", + averageRating: 2, + reviewCount: 1111, + reviewURL: BASE_URL + "/review3.html", + totalDownloads: 2222, + weeklyDownloads: 3333, + dailyUsers: 4444, + sourceURI: BASE_URL + "/test3.xpi", + repositoryStatus: 8, + size: 5555, + updateDate: new Date(1265033045000), + +}, { + id: "purchase1@tests.mozilla.org", + type: "extension", + version: "2.0", + creator: { + name: "Test Creator - Last Passing", + url: BASE_URL + "/creatorLastPassing.html" + }, + averageRating: 5, + repositoryStatus: 4, + purchaseURL: "http://localhost:" + PORT + "/purchaseURL1", + purchaseAmount: 5, + purchaseDisplayAmount: "$5", + icons: {} +}, { + id: "purchase2@tests.mozilla.org", + type: "extension", + version: "2.0", + creator: { + name: "Test Creator - Last Passing", + url: BASE_URL + "/creatorLastPassing.html" + }, + averageRating: 5, + repositoryStatus: 4, + purchaseURL: "http://localhost:" + PORT + "/purchaseURL2", + purchaseAmount: 10, + purchaseDisplayAmount: "$10", + icons: {} +}, { + id: "test-lastPassing@tests.mozilla.org", + type: "extension", + version: "2.0", + creator: { + name: "Test Creator - Last Passing", + url: BASE_URL + "/creatorLastPassing.html" + }, + averageRating: 5, + repositoryStatus: 4, + sourceURI: BASE_URL + "/addons/test_AddonRepository_3.xpi", + icons: {} +}]; + +const TOTAL_RESULTS = 1111; +const MAX_RESULTS = SEARCH_RESULTS.length; + +// Used to differentiate between testing that a search success +// or a search failure for retrieveRecommendedAddons and searchAddons +const FAILED_MAX_RESULTS = 9999; + +// Values for testing AddonRepository.getAddonsByIDs() +var GET_TEST = { + preference: PREF_GETADDONS_BYIDS, + preferenceValue: BASE_URL + "/%OS%/%VERSION%/%API_VERSION%/" + + "%API_VERSION%/%IDS%", + failedIDs: ["test1@tests.mozilla.org"], + failedURL: "/XPCShell/1/1.5/1.5/test1%40tests.mozilla.org", + successfulIDs: ["test1@tests.mozilla.org", + "{00000000-1111-2222-3333-444444444444}", + "test_AddonRepository_1@tests.mozilla.org"], + successfulURL: "/XPCShell/1/1.5/1.5/test1%40tests.mozilla.org," + + "%7B00000000-1111-2222-3333-444444444444%7D," + + "test_AddonRepository_1%40tests.mozilla.org" +}; + +// Values for testing AddonRepository.retrieveRecommendedAddons() +var RECOMMENDED_TEST = { + preference: PREF_GETADDONS_GETRECOMMENDED, + preferenceValue: BASE_URL + "/%OS%/%VERSION%/%API_VERSION%/" + + "%API_VERSION%/%MAX_RESULTS%", + failedURL: "/XPCShell/1/1.5/1.5/" + (2 * FAILED_MAX_RESULTS), + successfulURL: "/XPCShell/1/1.5/1.5/" + (2 * MAX_RESULTS) +}; + +// Values for testing AddonRepository.searchAddons() +var SEARCH_TEST = { + searchTerms: "odd=search:with&weird\"characters", + preference: PREF_GETADDONS_GETSEARCHRESULTS, + preferenceValue: BASE_URL + "/%OS%/%VERSION%/%API_VERSION%/" + + "%API_VERSION%/%MAX_RESULTS%/%TERMS%", + failedURL: "/XPCShell/1/1.5/1.5/" + (2 * FAILED_MAX_RESULTS) + + "/odd%3Dsearch%3Awith%26weird%22characters", + successfulURL: "/XPCShell/1/1.5/1.5/" + (2 * MAX_RESULTS) + + "/odd%3Dsearch%3Awith%26weird%22characters" +}; + +// Test that actual results and expected results are equal +function check_results(aActualAddons, aExpectedAddons, aAddonCount, aInstallNull) { + do_check_false(AddonRepository.isSearching); + + do_check_eq(aActualAddons.length, aAddonCount); + do_check_addons(aActualAddons, aExpectedAddons, ADDON_PROPERTIES); + + // Additional tests + aActualAddons.forEach(function check_each_addon(aActualAddon) { + // Separately check name so better messages are output when test fails + if (aActualAddon.name == "FAIL") + do_throw(aActualAddon.id + " - " + aActualAddon.description); + if (aActualAddon.name != "PASS") + do_throw(aActualAddon.id + " - " + "invalid add-on name " + aActualAddon.name); + + do_check_eq(aActualAddon.install == null, !!aInstallNull || !aActualAddon.sourceURI); + + // Check that sourceURI property consistent within actual addon + if (aActualAddon.install) + do_check_eq(aActualAddon.install.sourceURI.spec, aActualAddon.sourceURI.spec); + }); +} + +// Complete a search, also testing cancelSearch() and isSearching +function complete_search(aSearch, aSearchCallback) { + var failCallback = { + searchSucceeded: function(addons, length, total) { + do_throw("failCallback.searchSucceeded should not be called"); + end_test(); + }, + + searchFailed: function() { + do_throw("failCallback.searchFailed should not be called"); + end_test(); + } + }; + + var callbackCalled = false; + var testCallback = { + searchSucceeded: function(addons, length, total) { + do_throw("testCallback.searchSucceeded should not be called"); + end_test(); + }, + + searchFailed: function() { + callbackCalled = true; + } + }; + + // Should fail because cancelled it immediately + aSearch(failCallback); + do_check_true(AddonRepository.isSearching); + AddonRepository.cancelSearch(); + do_check_false(AddonRepository.isSearching); + + aSearch(aSearchCallback); + do_check_true(AddonRepository.isSearching); + + // searchFailed should be called immediately because already searching + aSearch(testCallback); + do_check_true(callbackCalled); + do_check_true(AddonRepository.isSearching); +} + + +function run_test() { + // Setup for test + do_test_pending(); + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9"); + + startupManager(); + + // Install an add-on so can check that it isn't returned in the results + installAllFiles([do_get_addon("test_AddonRepository_1")], function addon_1_install_callback() { + restartManager(); + + // Register other add-on XPI files + gServer.registerFile(INSTALL_URL2, + do_get_addon("test_AddonRepository_2")); + gServer.registerFile(INSTALL_URL3, + do_get_addon("test_AddonRepository_3")); + + // Register files used to test search failure + mapUrlToFile(GET_TEST.failedURL, + do_get_file("data/test_AddonRepository_failed.xml"), + gServer); + mapUrlToFile(RECOMMENDED_TEST.failedURL, + do_get_file("data/test_AddonRepository_failed.xml"), + gServer); + mapUrlToFile(SEARCH_TEST.failedURL, + do_get_file("data/test_AddonRepository_failed.xml"), + gServer); + + // Register files used to test search success + mapUrlToFile(GET_TEST.successfulURL, + do_get_file("data/test_AddonRepository_getAddonsByIDs.xml"), + gServer); + mapUrlToFile(RECOMMENDED_TEST.successfulURL, + do_get_file("data/test_AddonRepository.xml"), + gServer); + mapUrlToFile(SEARCH_TEST.successfulURL, + do_get_file("data/test_AddonRepository.xml"), + gServer); + + // Create an active AddonInstall so can check that it isn't returned in the results + AddonManager.getInstallForURL(BASE_URL + INSTALL_URL2, function addon_2_get(aInstall) { + try { + aInstall.install(); + } + catch (e) { + do_print("Failed to install add-on " + aInstall.sourceURI.spec); + do_report_unexpected_exception(e); + } + + // Create a non-active AddonInstall so can check that it is returned in the results + AddonManager.getInstallForURL(BASE_URL + INSTALL_URL3, + run_test_1, "application/x-xpinstall"); + }, "application/x-xpinstall"); + }); +} + +function end_test() { + let testDir = gProfD.clone(); + testDir.append("extensions"); + testDir.append("staged"); + gServer.stop(function() { + function loop() { + if (!testDir.exists()) { + do_print("Staged directory has been cleaned up"); + do_test_finished(); + } + do_print("Waiting 1 second until cleanup is complete"); + do_timeout(1000, loop); + } + loop(); + }); +} + +// Tests homepageURL, getRecommendedURL() and getSearchURL() +function run_test_1() { + function check_urls(aPreference, aGetURL, aTests) { + aTests.forEach(function(aTest) { + Services.prefs.setCharPref(aPreference, aTest.preferenceValue); + do_check_eq(aGetURL(aTest), aTest.expectedURL); + }); + } + + var urlTests = [{ + preferenceValue: BASE_URL, + expectedURL: BASE_URL + }, { + preferenceValue: BASE_URL + "/%OS%/%VERSION%", + expectedURL: BASE_URL + "/XPCShell/1" + }]; + + // Extra tests for AddonRepository.getSearchURL(); + var searchURLTests = [{ + searchTerms: "test", + preferenceValue: BASE_URL + "/search?q=%TERMS%", + expectedURL: BASE_URL + "/search?q=test" + }, { + searchTerms: "test search", + preferenceValue: BASE_URL + "/%TERMS%", + expectedURL: BASE_URL + "/test%20search" + }, { + searchTerms: "odd=search:with&weird\"characters", + preferenceValue: BASE_URL + "/%TERMS%", + expectedURL: BASE_URL + "/odd%3Dsearch%3Awith%26weird%22characters" + }]; + + // Setup tests for homepageURL, getRecommendedURL() and getSearchURL() + var tests = [{ + initiallyUndefined: true, + preference: PREF_GETADDONS_BROWSEADDONS, + urlTests: urlTests, + getURL: () => AddonRepository.homepageURL + }, { + initiallyUndefined: true, + preference: PREF_GETADDONS_BROWSERECOMMENDED, + urlTests: urlTests, + getURL: () => AddonRepository.getRecommendedURL() + }, { + initiallyUndefined: false, + preference: PREF_GETADDONS_BROWSESEARCHRESULTS, + urlTests: urlTests.concat(searchURLTests), + getURL: function getSearchURL(aTest) { + var searchTerms = aTest && aTest.searchTerms ? aTest.searchTerms + : "unused terms"; + return AddonRepository.getSearchURL(searchTerms); + } + }]; + + tests.forEach(function url_test(aTest) { + if (aTest.initiallyUndefined) { + // Preference is not defined by default + do_check_eq(Services.prefs.getPrefType(aTest.preference), + Services.prefs.PREF_INVALID); + do_check_eq(aTest.getURL(), DEFAULT_URL); + } + + check_urls(aTest.preference, aTest.getURL, aTest.urlTests); + }); + + run_test_getAddonsByID_fails(); +} + +// Tests failure of AddonRepository.getAddonsByIDs() +function run_test_getAddonsByID_fails() { + Services.prefs.setCharPref(GET_TEST.preference, GET_TEST.preferenceValue); + var callback = { + searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) { + do_throw("searchAddons should not have succeeded"); + end_test(); + }, + + searchFailed: function() { + do_check_false(AddonRepository.isSearching); + run_test_getAddonsByID_succeeds(); + } + }; + + complete_search(function complete_search_fail_callback(aCallback) { + AddonRepository.getAddonsByIDs(GET_TEST.failedIDs, aCallback); + }, callback); +} + +// Tests success of AddonRepository.getAddonsByIDs() +function run_test_getAddonsByID_succeeds() { + var callback = { + searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) { + do_check_eq(aTotalResults, -1); + check_results(aAddonsList, GET_RESULTS, aAddonCount, true); + run_test_retrieveRecommended_fails(); + }, + + searchFailed: function() { + do_throw("searchAddons should not have failed"); + end_test(); + } + }; + + complete_search(function complete_search_succeed_callback(aCallback) { + AddonRepository.getAddonsByIDs(GET_TEST.successfulIDs, aCallback); + }, callback); +} + +// Tests failure of AddonRepository.retrieveRecommendedAddons() +function run_test_retrieveRecommended_fails() { + Services.prefs.setCharPref(RECOMMENDED_TEST.preference, + RECOMMENDED_TEST.preferenceValue); + var callback = { + searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) { + do_throw("retrieveRecommendedAddons should not have succeeded"); + end_test(); + }, + + searchFailed: function() { + do_check_false(AddonRepository.isSearching); + run_test_retrieveRecommended_succeed(); + } + }; + + complete_search(function retrieveRecommended_failing_callback(aCallback) { + AddonRepository.retrieveRecommendedAddons(FAILED_MAX_RESULTS, aCallback); + }, callback); +} + +// Tests success of AddonRepository.retrieveRecommendedAddons() +function run_test_retrieveRecommended_succeed() { + var callback = { + searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) { + do_check_eq(aTotalResults, -1); + check_results(aAddonsList, SEARCH_RESULTS, aAddonCount); + run_test_searchAddons_fails(); + }, + + searchFailed: function() { + do_throw("retrieveRecommendedAddons should not have failed"); + end_test(); + } + }; + + complete_search(function retrieveRecommended_succeed_callback(aCallback) { + AddonRepository.retrieveRecommendedAddons(MAX_RESULTS, aCallback); + }, callback); +} + +// Tests failure of AddonRepository.searchAddons() +function run_test_searchAddons_fails() { + Services.prefs.setCharPref(SEARCH_TEST.preference, SEARCH_TEST.preferenceValue); + var callback = { + searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) { + do_throw("searchAddons should not have succeeded"); + end_test(); + }, + + searchFailed: function() { + do_check_false(AddonRepository.isSearching); + run_test_searchAddons_succeeds(); + } + }; + + complete_search(function(aCallback) { + var searchTerms = SEARCH_TEST.searchTerms; + AddonRepository.searchAddons(searchTerms, FAILED_MAX_RESULTS, aCallback); + }, callback); +} + +// Tests success of AddonRepository.searchAddons() +function run_test_searchAddons_succeeds() { + var callback = { + searchSucceeded: function(aAddonsList, aAddonCount, aTotalResults) { + do_check_eq(aTotalResults, TOTAL_RESULTS); + check_results(aAddonsList, SEARCH_RESULTS, aAddonCount); + end_test(); + }, + + searchFailed: function() { + do_throw("searchAddons should not have failed"); + end_test(); + } + }; + + complete_search(function(aCallback) { + var searchTerms = SEARCH_TEST.searchTerms; + AddonRepository.searchAddons(searchTerms, MAX_RESULTS, aCallback); + }, callback); +} + -- cgit v1.2.3