diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 036712d2e948..37f0228ce720 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -43,8 +43,8 @@ pref("extensions.webextOptionalPermissionPrompts", true); // Preferences for AMO integration pref("extensions.getAddons.cache.enabled", true); -pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%"); -pref("extensions.getAddons.getWithPerformance.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%"); +pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/api/v3/addons/search/?guid=%IDS%&lang=%LOCALE%"); +pref("extensions.getAddons.compatOverides.url", "https://services.addons.mozilla.org/api/v3/addons/compat-override/?guid=%IDS%&lang=%LOCALE%"); pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%&platform=%OS%&appver=%VERSION%"); pref("extensions.webservice.discoverURL", "https://discovery.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%/%COMPATIBILITY_MODE%"); pref("extensions.getAddons.link.url", "https://addons.mozilla.org/%LOCALE%/firefox/"); diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 01d836e32360..939a8b1cd5c1 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -212,8 +212,8 @@ pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla pref("extensions.getAddons.cache.enabled", true); pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/android/search?q=%TERMS%&platform=%OS%&appver=%VERSION%"); pref("extensions.getAddons.browseAddons", "https://addons.mozilla.org/%LOCALE%/android/"); -pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/android/api/%API_VERSION%/search/guid:%IDS%?src=mobile&appOS=%OS%&appVersion=%VERSION%"); -pref("extensions.getAddons.getWithPerformance.url", "https://services.addons.mozilla.org/%LOCALE%/android/api/%API_VERSION%/search/guid:%IDS%?src=mobile&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%"); +pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/api/v3/addons/search/?guid=%IDS%&lang=%LOCALE%"); +pref("extensions.getAddons.compatOverides.url", "https://services.addons.mozilla.org/api/v3/addons/compat-override/?guid=%IDS%&lang=%LOCALE%"); /* preference for the locale picker */ pref("extensions.getLocales.get.url", ""); diff --git a/services/sync/modules/addonutils.js b/services/sync/modules/addonutils.js index 615766f7c665..cc7b0b13e165 100644 --- a/services/sync/modules/addonutils.js +++ b/services/sync/modules/addonutils.js @@ -202,19 +202,9 @@ AddonUtilsInternal.prototype = { ids.push(addon.id); } - const {addons, addonsLength} = await new Promise((res, rej) => { - AddonRepository.getAddonsByIDs(ids, { - searchSucceeded: (addons, addonsLength, total) => { - res({addons, addonsLength}); - }, - searchFailed() { - rej(new Error("AddonRepository search failed")); - } - }); - }); - - this._log.info("Found " + addonsLength + "/" + ids.length + - " add-ons during repository search."); + let addons = await AddonRepository.getAddonsByIDs(ids); + this._log.info(`Found ${addons.length} / ${ids.length}` + + " add-ons during repository search."); let ourResult = { installedIDs: [], @@ -224,10 +214,6 @@ AddonUtilsInternal.prototype = { errors: [] }; - if (!addonsLength) { - return ourResult; - } - let toInstall = []; // Rewrite the "src" query string parameter of the source URI to note diff --git a/services/sync/tests/unit/addon1-search.json b/services/sync/tests/unit/addon1-search.json new file mode 100644 index 000000000000..55f8af885767 --- /dev/null +++ b/services/sync/tests/unit/addon1-search.json @@ -0,0 +1,21 @@ +{ + "next": null, + "results": [ + { + "name": "Non-Restartless Test Extension", + "type": "extension", + "guid": "addon1@tests.mozilla.org", + "current_version": { + "version": "1.0", + "files": [ + { + "platform": "all", + "size": 485, + "url": "http://127.0.0.1:8888/addon1.xpi" + } + ] + }, + "last_updated": "2011-09-05T20:42:09Z" + } + ] +} diff --git a/services/sync/tests/unit/addon1-search.xml b/services/sync/tests/unit/addon1-search.xml deleted file mode 100644 index 1211d0c97b6c..000000000000 --- a/services/sync/tests/unit/addon1-search.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - Non-Restartless Test Extension - Extension - addon1@tests.mozilla.org - addon11 - 1.0 - - - Firefox - 1 - 3.6 - * - xpcshell@tests.mozilla.org - - ALL - - http://127.0.0.1:8888/addon1.xpi - - 2009-09-14T04:47:42Z - - - 2011-09-05T20:42:09Z - - - diff --git a/services/sync/tests/unit/bootstrap1-search.json b/services/sync/tests/unit/bootstrap1-search.json new file mode 100644 index 000000000000..8cd1cf43ed11 --- /dev/null +++ b/services/sync/tests/unit/bootstrap1-search.json @@ -0,0 +1,21 @@ +{ + "next": null, + "results": [ + { + "name": "Restartless Test Extension", + "type": "extension", + "guid": "bootstrap1@tests.mozilla.org", + "current_version": { + "version": "1.0", + "files": [ + { + "platform": "all", + "size": 485, + "url": "http://127.0.0.1:8888/bootstrap1.xpi" + } + ] + }, + "last_updated": "2011-09-05T20:42:09Z" + } + ] +} diff --git a/services/sync/tests/unit/bootstrap1-search.xml b/services/sync/tests/unit/bootstrap1-search.xml deleted file mode 100644 index b4538fba0d49..000000000000 --- a/services/sync/tests/unit/bootstrap1-search.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - Restartless Test Extension - Extension - bootstrap1@tests.mozilla.org - bootstrap1 - 1.0 - - - Firefox - 1 - 3.6 - * - xpcshell@tests.mozilla.org - - ALL - - http://127.0.0.1:8888/bootstrap1.xpi - - 2009-09-14T04:47:42Z - - - 2011-09-05T20:42:09Z - - - diff --git a/services/sync/tests/unit/missing-sourceuri.json b/services/sync/tests/unit/missing-sourceuri.json new file mode 100644 index 000000000000..dcd487726a9e --- /dev/null +++ b/services/sync/tests/unit/missing-sourceuri.json @@ -0,0 +1,20 @@ +{ + "next": null, + "results": [ + { + "name": "Restartless Test Extension", + "type": "extension", + "guid": "missing-sourceuri@tests.mozilla.org", + "current_version": { + "version": "1.0", + "files": [ + { + "platform": "all", + "size": 485 + } + ] + }, + "last_updated": "2011-09-05T20:42:09Z" + } + ] +} diff --git a/services/sync/tests/unit/missing-sourceuri.xml b/services/sync/tests/unit/missing-sourceuri.xml deleted file mode 100644 index dbc83e17fe30..000000000000 --- a/services/sync/tests/unit/missing-sourceuri.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - Restartless Test Extension - Extension - missing-sourceuri@tests.mozilla.org - missing-sourceuri - 1.0 - - - Firefox - 1 - 3.6 - * - {3e3ba16c-1675-4e88-b9c8-afef81b3d2ef} - - ALL - - - - 2009-09-14T04:47:42Z - - - 2011-09-05T20:42:09Z - - - diff --git a/services/sync/tests/unit/missing-xpi-search.json b/services/sync/tests/unit/missing-xpi-search.json new file mode 100644 index 000000000000..55f6432b291b --- /dev/null +++ b/services/sync/tests/unit/missing-xpi-search.json @@ -0,0 +1,21 @@ +{ + "next": null, + "results": [ + { + "name": "Non-Restartless Test Extension", + "type": "extension", + "guid": "missing-xpi@tests.mozilla.org", + "current_version": { + "version": "1.0", + "files": [ + { + "platform": "all", + "size": 485, + "url": "http://127.0.0.1:8888/THIS_DOES_NOT_EXIST.xpi" + } + ] + }, + "last_updated": "2011-09-05T20:42:09Z" + } + ] +} diff --git a/services/sync/tests/unit/missing-xpi-search.xml b/services/sync/tests/unit/missing-xpi-search.xml deleted file mode 100644 index 9b547cdb36b4..000000000000 --- a/services/sync/tests/unit/missing-xpi-search.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - Restartless Test Extension - Extension - missing-xpi@tests.mozilla.org - missing-xpi - 1.0 - - - Firefox - 1 - 3.6 - * - {3e3ba16c-1675-4e88-b9c8-afef81b3d2ef} - - ALL - - http://127.0.0.1:8888/THIS_DOES_NOT_EXIST.xpi - - 2009-09-14T04:47:42Z - - - 2011-09-05T20:42:09Z - - - diff --git a/services/sync/tests/unit/rewrite-search.json b/services/sync/tests/unit/rewrite-search.json new file mode 100644 index 000000000000..740b6f2c306c --- /dev/null +++ b/services/sync/tests/unit/rewrite-search.json @@ -0,0 +1,21 @@ +{ + "next": null, + "results": [ + { + "name": "Rewrite Test Extension", + "type": "extension", + "guid": "rewrite@tests.mozilla.org", + "current_version": { + "version": "1.0", + "files": [ + { + "platform": "all", + "size": 485, + "url": "http://127.0.0.1:8888/require.xpi?src=api" + } + ] + }, + "last_updated": "2011-09-05T20:42:09Z" + } + ] +} diff --git a/services/sync/tests/unit/rewrite-search.xml b/services/sync/tests/unit/rewrite-search.xml deleted file mode 100644 index 15476b1abf98..000000000000 --- a/services/sync/tests/unit/rewrite-search.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - Rewrite Test Extension - Extension - rewrite@tests.mozilla.org - rewrite - 1.0 - - - Firefox - 1 - 3.6 - * - xpcshell@tests.mozilla.org - - ALL - - http://127.0.0.1:8888/require.xpi?src=api - - 2009-09-14T04:47:42Z - - - 2011-09-05T20:42:09Z - - - diff --git a/services/sync/tests/unit/systemaddon-search.json b/services/sync/tests/unit/systemaddon-search.json new file mode 100644 index 000000000000..a81271491807 --- /dev/null +++ b/services/sync/tests/unit/systemaddon-search.json @@ -0,0 +1,21 @@ +{ + "next": null, + "results": [ + { + "name": "System Add-on Test", + "type": "extension", + "guid": "system1@tests.mozilla.org", + "current_version": { + "version": "1.0", + "files": [ + { + "platform": "all", + "size": 999, + "url": "http://127.0.0.1:8888/system.xpi" + } + ] + }, + "last_updated": "2011-09-05T20:42:09Z" + } + ] +} diff --git a/services/sync/tests/unit/systemaddon-search.xml b/services/sync/tests/unit/systemaddon-search.xml deleted file mode 100644 index d34e3937c347..000000000000 --- a/services/sync/tests/unit/systemaddon-search.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - System Add-on Test - Extension - system1@tests.mozilla.org - addon11 - 1.0 - - - Firefox - 1 - 3.6 - * - xpcshell@tests.mozilla.org - - ALL - - http://127.0.0.1:8888/system.xpi - - 2009-09-14T04:47:42Z - - - 2011-09-05T20:42:09Z - - - diff --git a/services/sync/tests/unit/test_addon_utils.js b/services/sync/tests/unit/test_addon_utils.js index dd211bdf61a4..24edf8a45121 100644 --- a/services/sync/tests/unit/test_addon_utils.js +++ b/services/sync/tests/unit/test_addon_utils.js @@ -24,10 +24,10 @@ function createAndStartHTTPServer(port = HTTP_PORT) { let server = new HttpServer(); server.registerFile("/search/guid:missing-sourceuri%40tests.mozilla.org", - do_get_file("missing-sourceuri.xml")); + do_get_file("missing-sourceuri.json")); server.registerFile("/search/guid:rewrite%40tests.mozilla.org", - do_get_file("rewrite-search.xml")); + do_get_file("rewrite-search.json")); server.start(port); diff --git a/services/sync/tests/unit/test_addons_engine.js b/services/sync/tests/unit/test_addons_engine.js index 196765ac5a1b..20c7e30c7d09 100644 --- a/services/sync/tests/unit/test_addons_engine.js +++ b/services/sync/tests/unit/test_addons_engine.js @@ -188,7 +188,7 @@ add_task(async function test_disabled_install_semantics() { let amoServer = new HttpServer(); amoServer.registerFile("/search/guid:addon1%40tests.mozilla.org", - do_get_file("addon1-search.xml")); + do_get_file("addon1-search.json")); let installXPI = ExtensionsTestPath("/addons/test_install1.xpi"); amoServer.registerFile("/addon1.xpi", do_get_file(installXPI)); diff --git a/services/sync/tests/unit/test_addons_store.js b/services/sync/tests/unit/test_addons_store.js index 2385f7b0af31..357ab082b2d7 100644 --- a/services/sync/tests/unit/test_addons_store.js +++ b/services/sync/tests/unit/test_addons_store.js @@ -70,14 +70,14 @@ function createAndStartHTTPServer(port) { let bootstrap1XPI = ExtensionsTestPath("/addons/test_bootstrap1_1.xpi"); server.registerFile("/search/guid:bootstrap1%40tests.mozilla.org", - do_get_file("bootstrap1-search.xml")); + do_get_file("bootstrap1-search.json")); server.registerFile("/bootstrap1.xpi", do_get_file(bootstrap1XPI)); server.registerFile("/search/guid:missing-xpi%40tests.mozilla.org", - do_get_file("missing-xpi-search.xml")); + do_get_file("missing-xpi-search.json")); server.registerFile("/search/guid:system1%40tests.mozilla.org", - do_get_file("systemaddon-search.xml")); + do_get_file("systemaddon-search.json")); server.registerFile("/system.xpi", systemAddonFile); server.start(port); diff --git a/services/sync/tests/unit/xpcshell.ini b/services/sync/tests/unit/xpcshell.ini index 1d6d960775f2..be00d5d9e271 100644 --- a/services/sync/tests/unit/xpcshell.ini +++ b/services/sync/tests/unit/xpcshell.ini @@ -3,14 +3,14 @@ head = head_appinfo.js ../../../common/tests/unit/head_helpers.js head_helpers.j firefox-appdir = browser skip-if = asan # asan crashes, bug 1344085 support-files = - addon1-search.xml - bootstrap1-search.xml - missing-sourceuri.xml - missing-xpi-search.xml + addon1-search.json + bootstrap1-search.json + missing-sourceuri.json + missing-xpi-search.json places_v10_from_v11.sqlite - rewrite-search.xml + rewrite-search.json sync_ping_schema.json - systemaddon-search.xml + systemaddon-search.json !/services/common/tests/unit/head_helpers.js !/toolkit/mozapps/extensions/test/xpcshell/head_addons.js !/toolkit/components/extensions/test/xpcshell/head_sync.js diff --git a/toolkit/mozapps/extensions/internal/AddonRepository.jsm b/toolkit/mozapps/extensions/internal/AddonRepository.jsm index 4a312c41e79a..a2a11cb13679 100644 --- a/toolkit/mozapps/extensions/internal/AddonRepository.jsm +++ b/toolkit/mozapps/extensions/internal/AddonRepository.jsm @@ -25,7 +25,7 @@ const PREF_GETADDONS_CACHE_TYPES = "extensions.getAddons.cache.types"; const PREF_GETADDONS_CACHE_ID_ENABLED = "extensions.%ID%.getAddons.cache.enabled"; const PREF_GETADDONS_BROWSEADDONS = "extensions.getAddons.browseAddons"; const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url"; -const PREF_GETADDONS_BYIDS_PERFORMANCE = "extensions.getAddons.getWithPerformance.url"; +const PREF_COMPAT_OVERRIDES = "extensions.getAddons.compatOverides.url"; const PREF_GETADDONS_BROWSESEARCHRESULTS = "extensions.getAddons.search.browseURL"; const PREF_GETADDONS_DB_SCHEMA = "extensions.getAddons.databaseSchema"; @@ -33,9 +33,6 @@ const PREF_METADATA_LASTUPDATE = "extensions.getAddons.cache.lastUpdat const PREF_METADATA_UPDATETHRESHOLD_SEC = "extensions.getAddons.cache.updateThreshold"; const DEFAULT_METADATA_UPDATETHRESHOLD_SEC = 172800; // two days -const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"; - -const API_VERSION = "1.5"; const DEFAULT_CACHE_TYPES = "extension,theme,locale,dictionary"; const FILE_DATABASE = "addons.json"; @@ -46,6 +43,7 @@ const DB_BATCH_TIMEOUT_MS = 50; const BLANK_DB = function() { return { addons: new Map(), + compatOverrides: new Map(), schema: DB_SCHEMA }; }; @@ -59,32 +57,6 @@ const LOGGER_ID = "addons.repository"; // (Requires AddonManager.jsm) var logger = Log.repository.getLogger(LOGGER_ID); -// A map between XML keys to AddonSearchResult keys for string values -// that require no extra parsing from XML -const STRING_KEY_MAP = { - name: "name", - version: "version", - homepage: "homepageURL", - support: "supportURL" -}; - -// A map between XML keys to AddonSearchResult keys for string values -// that require parsing from HTML -const HTML_KEY_MAP = { - summary: "description", - description: "fullDescription", - developer_comments: "developerComments", - eula: "eula" -}; - -// A map between XML keys to AddonSearchResult keys for integer values -// that require no extra parsing from XML -const INTEGER_KEY_MAP = { - total_downloads: "totalDownloads", - weekly_downloads: "weeklyDownloads", - daily_users: "dailyUsers" -}; - function convertHTMLToPlainText(html) { if (!html) return html; @@ -211,11 +183,6 @@ AddonSearchResult.prototype = { */ homepageURL: null, - /** - * The homepage for the add-on - */ - learnmoreURL: null, - /** * The support URL for the add-on */ @@ -226,11 +193,6 @@ AddonSearchResult.prototype = { */ contributionURL: null, - /** - * The suggested contribution amount - */ - contributionAmount: null, - /** * The rating of the add-on, 0-5 */ @@ -246,21 +208,11 @@ AddonSearchResult.prototype = { */ reviewURL: null, - /** - * The total number of times the add-on was downloaded - */ - totalDownloads: null, - /** * The number of times the add-on was downloaded the current week */ weeklyDownloads: null, - /** - * The number of daily users for the add-on - */ - dailyUsers: null, - /** * AddonInstall object generated from the add-on XPI url */ @@ -271,11 +223,6 @@ AddonSearchResult.prototype = { */ sourceURI: null, - /** - * The status of the add-on in the repository (e.g. 4 = "Public") - */ - repositoryStatus: null, - /** * The size of the add-on's files in bytes. For an add-on that have not yet * been downloaded this may be an estimated value. @@ -287,12 +234,6 @@ AddonSearchResult.prototype = { */ updateDate: null, - /** - * Array of AddonCompatibilityOverride objects, that describe overrides for - * compatibility with an application versions. - **/ - compatibilityOverrides: null, - toJSON() { let json = {}; @@ -342,60 +283,48 @@ AddonSearchResult.prototype = { * installed. */ var AddonRepository = { + /** + * The homepage for visiting this repository. If the corresponding preference + * is not defined, defaults to about:blank. + */ + get homepageURL() { + let url = this._formatURLPref(PREF_GETADDONS_BROWSEADDONS, {}); + return (url != null) ? url : "about:blank"; + }, + + /** + * Retrieves the url that can be visited to see search results for the given + * terms. If the corresponding preference is not defined, defaults to + * about:blank. + * + * @param aSearchTerms + * Search terms used to search the repository + */ + getSearchURL(aSearchTerms) { + let url = this._formatURLPref(PREF_GETADDONS_BROWSESEARCHRESULTS, { + TERMS: aSearchTerms, + }); + return (url != null) ? url : "about:blank"; + }, + /** * Whether caching is currently enabled */ get cacheEnabled() { - let preference = PREF_GETADDONS_CACHE_ENABLED; - return Services.prefs.getBoolPref(preference, false); + return Services.prefs.getBoolPref(PREF_GETADDONS_CACHE_ENABLED, false); }, - // A cache of the add-ons stored in the database - _addons: null, - - // Whether a search is currently in progress - _searching: false, - - // XHR associated with the current request - _request: null, - - /* - * Addon search results callback object that contains two functions - * - * searchSucceeded - Called when a search has suceeded. - * - * @param aAddons - * An array of the add-on results. In the case of searching for - * specific terms the ordering of results may be determined by - * the search provider. - * @param aAddonCount - * The length of aAddons - * @param aTotalResults - * The total results actually available in the repository - * - * - * searchFailed - Called when an error occurred when performing a search. - */ - _callback: null, - - // Maximum number of results to return - _maxResults: null, - /** * Shut down AddonRepository * return: promise{integer} resolves with the result of flushing * the AddonRepository database */ shutdown() { - this.cancelSearch(); - - this._addons = null; return AddonDatabase.shutdown(false); }, metadataAge() { let now = Math.round(Date.now() / 1000); - let lastUpdate = Services.prefs.getIntPref(PREF_METADATA_LASTUPDATE, 0); return Math.max(0, now - lastUpdate); }, @@ -415,8 +344,8 @@ var AddonRepository = { * data for the given add-on, if any is available. */ async getCompatibilityOverrides(aId) { - let addon = await new Promise(resolve => this.getCachedAddonByID(aId, resolve)); - return addon ? addon.compatibilityOverrides : null; + await AddonDatabase.openConnection(); + return AddonDatabase.getCompatOverrides(aId); }, /** @@ -433,10 +362,7 @@ var AddonRepository = { * is a compatibility override for the addon. */ getCompatibilityOverridesSync(aId) { - if (this._addons == null || !this._addons.has(aId)) { - return null; - } - return this._addons.get(aId).compatibilityOverrides; + return AddonDatabase.getCompatOverrides(aId); }, /** @@ -444,46 +370,33 @@ var AddonRepository = { * add-on is not found) is passed to the specified callback. If caching is * disabled, null is passed to the specified callback. * + * The callback variant exists only for existing code in XPIProvider.jsm + * and XPIProviderUtils.jsm that requires a synchronous callback, yuck. + * * @param aId * The id of the add-on to get - * @param aCallback - * The callback to pass the result back to */ async getCachedAddonByID(aId, aCallback) { if (!aId || !this.cacheEnabled) { - aCallback(null); - return; + if (aCallback) { + aCallback(null); + } + return null; } - function getAddon(aAddons) { - aCallback(aAddons.get(aId) || null); + if (aCallback && AddonDatabase._loaded) { + let addon = AddonDatabase.getAddon(aId); + aCallback(addon); + return addon; } - if (this._addons == null) { - AddonDatabase.retrieveStoredData().then(aAddons => { - this._addons = aAddons; - getAddon(aAddons); - }); + await AddonDatabase.openConnection(); - return; + let addon = AddonDatabase.getAddon(aId); + if (aCallback) { + aCallback(addon); } - - getAddon(this._addons); - }, - - /** - * Asynchronously repopulate cache so it only contains the add-ons - * corresponding to the specified ids. If caching is disabled, - * the cache is completely removed. - * - * @param aTimeout - * (Optional) timeout in milliseconds to abandon the XHR request - * if we have not received a response from the server. - * @return Promise{null} - * Resolves when the metadata ping is complete - */ - repopulateCache(aTimeout) { - return this._repopulateCacheInternal(false, aTimeout); + return addon; }, /* @@ -491,12 +404,146 @@ var AddonRepository = { * @return Promise{null} resolves when the database is deleted */ _clearCache() { - this._addons = null; return AddonDatabase.delete().then(() => AddonManagerPrivate.updateAddonRepositoryData()); }, - async _repopulateCacheInternal(aSendPerformance, aTimeout) { + /** + * Fetch data from an API where the results may span multiple "pages". + * This function will take care of issuing multiple requests until all + * the results have been fetched, and will coalesce them all into a + * single return value. The handling here is specific to the way AMO + * implements paging (ie a JSON result with a "next" property). + * + * @param {string} startURL + * URL for the first page of results + * @param {function} handler + * This function will be called once per page of results, + * it should return an array of objects (the type depends + * on the particular API being called of course). + * + * @returns Promise{array} An array of all the individual results from + * the API call(s). + */ + _fetchPaged(ids, pref, handler) { + let startURL = this._formatURLPref(pref, {IDS: ids.join(",")}); + let results = []; + + const fetchNextPage = (url) => { + return new Promise((resolve, reject) => { + let request = new ServiceRequest(); + request.mozBackgroundRequest = true; + request.open("GET", url, true); + request.responseType = "json"; + + request.addEventListener("error", aEvent => { + reject(new Error(`GET ${url} failed`)); + }); + request.addEventListener("timeout", aEvent => { + reject(new Error(`GET ${url} timed out`)); + }); + request.addEventListener("load", aEvent => { + let response = request.response; + if (!response || (request.status != 200 && request.status != 0)) { + reject(new Error(`GET ${url} failed (status ${request.status})`)); + return; + } + + try { + let newResults = handler(response.results).filter(e => ids.includes(e.id)); + results.push(...newResults); + } catch (err) { + reject(err); + } + + if (response.next) { + resolve(fetchNextPage(response.next)); + } + + resolve(results); + }); + + request.send(null); + }); + }; + + return fetchNextPage(startURL); + }, + + /** + * Fetch metadata for a given set of addons from AMO. + * + * @param aIDs + * The array of ids to retrieve metadata for. + * @returns {array} + */ + async getAddonsByIDs(aIDs) { + return this._fetchPaged(aIDs, PREF_GETADDONS_BYIDS, + results => results.map( + entry => this._parseAddon(entry))); + }, + + /** + * Fetch both addon metadata and compatibility override data for + * a set of addons. + * + * @param {array} aIDs + * A list of addon IDs to fetch information about. + * + * @returns {object} + * The returned object has two properties: `addons`, which is an + * array of AddonSearchResult objects containing the addon metadata, + * and `overrides, which is an array of compatibility override + * objects. + */ + async _getFullData(aIDs) { + let metadataPromise = this.getAddonsByIDs(aIDs, false); + + let overridesPromise = this._fetchPaged(aIDs, PREF_COMPAT_OVERRIDES, + results => results.map( + entry => this._parseCompatEntry(entry))); + let addons = [], overrides = []; + try { + [addons, overrides] = await Promise.all([metadataPromise, overridesPromise]); + } catch (err) { + logger.error(`Error in addon metadata check: ${err.message}`); + } + + return {addons, overrides}; + }, + + /** + * Asynchronously add add-ons to the cache corresponding to the specified + * ids. If caching is disabled, the cache is unchanged. + * + * @param aIds + * The array of add-on ids to add to the cache + */ + async cacheAddons(aIds) { + logger.debug("cacheAddons: enabled " + this.cacheEnabled + " IDs " + aIds.toSource()); + if (!this.cacheEnabled) { + return []; + } + + let ids = await getAddonsToCache(aIds); + + // If there are no add-ons to cache, act as if caching is disabled + if (ids.length == 0) { + return []; + } + + let {addons, overrides} = await this._getFullData(ids); + await AddonDatabase.update(addons, overrides); + + return Array.from(addons.values()); + }, + + /** + * Performs the daily background update check. + * + * @return Promise{null} Resolves when the metadata update is complete. + */ + async backgroundUpdateCheck() { let allAddons = await AddonManager.getAllAddons(); // Completely remove cache if caching is not enabled @@ -518,769 +565,156 @@ var AddonRepository = { return; } - await new Promise((resolve, reject) => - this._beginGetAddons(addonsToCache, { - searchSucceeded: aAddons => { - this._addons = new Map(); - for (let addon of aAddons) { - this._addons.set(addon.id, addon); - } - AddonDatabase.repopulate(aAddons, resolve); - }, - searchFailed: () => { - logger.warn("Search failed when repopulating cache"); - resolve(); - } - }, aSendPerformance, aTimeout)); + let {addons, overrides} = await this._getFullData(addonsToCache); + + AddonDatabase.repopulate(addons, overrides); // Always call AddonManager updateAddonRepositoryData after we refill the cache await AddonManagerPrivate.updateAddonRepositoryData(); }, - /** - * Asynchronously add add-ons to the cache corresponding to the specified - * ids. If caching is disabled, the cache is unchanged and the callback is - * immediately called if it is defined. + /* + * Creates an AddonSearchResult by parsing an entry from the AMO API. * - * @param aIds - * The array of add-on ids to add to the cache - * @param aCallback - * The optional callback to call once complete + * @param aEntry + * An entry from the AMO search API to parse. + * @return Result object containing the parsed AddonSearchResult */ - cacheAddons(aIds, aCallback) { - logger.debug("cacheAddons: enabled " + this.cacheEnabled + " IDs " + aIds.toSource()); - if (!this.cacheEnabled) { - if (aCallback) - aCallback(); - return; + _parseAddon(aEntry) { + let addon = new AddonSearchResult(aEntry.guid); + + addon.name = aEntry.name; + if (typeof aEntry.current_version == "object") { + addon.version = String(aEntry.current_version.version); + if (Array.isArray(aEntry.current_version.files)) { + for (let file of aEntry.current_version.files) { + if (file.platform == "all" || file.platform == Services.appinfo.OS.toLowerCase()) { + if (file.url) { + addon.sourceURI = NetUtil.newURI(file.url); + } + addon.size = Number(file.size); + break; + } + } + } + } + addon.homepageURL = aEntry.homepage; + addon.supportURL = aEntry.support_url; + + addon.description = convertHTMLToPlainText(aEntry.summary); + addon.fullDescription = convertHTMLToPlainText(aEntry.description); + + addon.weeklyDownloads = aEntry.weekly_downloads; + + switch (aEntry.type) { + case "persona": + addon.type = "theme"; + break; + + case "language": + addon.type = "locale"; + break; + + default: + addon.type = aEntry.type; + break; } - getAddonsToCache(aIds).then(aAddons => { - // If there are no add-ons to cache, act as if caching is disabled - if (aAddons.length == 0) { - if (aCallback) - aCallback(); - return; + if (Array.isArray(aEntry.authors)) { + let authors = aEntry.authors.map(author => new AddonManagerPrivate.AddonAuthor(author.name, author.url)); + if (authors.length > 0) { + addon.creator = authors[0]; + addon.developers = authors.slice(1); } + } - this.getAddonsByIDs(aAddons, { - searchSucceeded: aAddons => { - for (let addon of aAddons) { - this._addons.set(addon.id, addon); - } - AddonDatabase.insertAddons(aAddons, aCallback); - }, - searchFailed: () => { - logger.warn("Search failed when adding add-ons to cache"); - if (aCallback) - aCallback(); - } + if (typeof aEntry.previews == "object") { + addon.screenshots = aEntry.previews.map(shot => { + let safeSize = orig => Array.isArray(orig) && orig.length >= 2 ? orig : [null, null]; + let imageSize = safeSize(shot.image_size); + let thumbSize = safeSize(shot.thumbnail_size); + return new AddonManagerPrivate.AddonScreenshot(shot.image_url, + imageSize[0], + imageSize[1], + shot.thumbnail_url, + thumbSize[0], + thumbSize[1], + shot.caption); }); - }); - }, - - /** - * The homepage for visiting this repository. If the corresponding preference - * is not defined, defaults to about:blank. - */ - get homepageURL() { - let url = this._formatURLPref(PREF_GETADDONS_BROWSEADDONS, {}); - return (url != null) ? url : "about:blank"; - }, - - /** - * Returns whether this instance is currently performing a search. New - * searches will not be performed while this is the case. - */ - get isSearching() { - return this._searching; - }, - - /** - * Retrieves the url that can be visited to see search results for the given - * terms. If the corresponding preference is not defined, defaults to - * about:blank. - * - * @param aSearchTerms - * Search terms used to search the repository - */ - getSearchURL(aSearchTerms) { - let url = this._formatURLPref(PREF_GETADDONS_BROWSESEARCHRESULTS, { - TERMS: encodeURIComponent(aSearchTerms) - }); - return (url != null) ? url : "about:blank"; - }, - - /** - * Cancels the search in progress. If there is no search in progress this - * does nothing. - */ - cancelSearch() { - this._searching = false; - if (this._request) { - this._request.abort(); - this._request = null; - } - this._callback = null; - }, - - /** - * Begins a search for add-ons in this repository by ID. Results will be - * passed to the given callback. - * - * @param aIDs - * The array of ids to search for - * @param aCallback - * The callback to pass results to - */ - getAddonsByIDs(aIDs, aCallback) { - return this._beginGetAddons(aIDs, aCallback, false); - }, - - /** - * Begins a search of add-ons, potentially sending performance data. - * - * @param aIDs - * Array of ids to search for. - * @param aCallback - * Function to pass results to. - * @param aSendPerformance - * Boolean indicating whether to send performance data with the - * request. - * @param aTimeout - * (Optional) timeout in milliseconds to abandon the XHR request - * if we have not received a response from the server. - */ - _beginGetAddons(aIDs, aCallback, aSendPerformance, aTimeout) { - let ids = aIDs.slice(0); - - let params = { - API_VERSION, - IDS: ids.map(encodeURIComponent).join(",") - }; - - let pref = PREF_GETADDONS_BYIDS; - - if (aSendPerformance) { - let type = Services.prefs.getPrefType(PREF_GETADDONS_BYIDS_PERFORMANCE); - if (type == Services.prefs.PREF_STRING) { - pref = PREF_GETADDONS_BYIDS_PERFORMANCE; - - let startupInfo = Services.startup.getStartupInfo(); - - params.TIME_MAIN = ""; - params.TIME_FIRST_PAINT = ""; - params.TIME_SESSION_RESTORED = ""; - if (startupInfo.process) { - if (startupInfo.main) { - params.TIME_MAIN = startupInfo.main - startupInfo.process; - } - if (startupInfo.firstPaint) { - params.TIME_FIRST_PAINT = startupInfo.firstPaint - - startupInfo.process; - } - if (startupInfo.sessionRestored) { - params.TIME_SESSION_RESTORED = startupInfo.sessionRestored - - startupInfo.process; - } - } - } } - let url = this._formatURLPref(pref, params); + addon.contributionURL = aEntry.contributions_url; - let handleResults = (aElements, aTotalResults, aCompatData) => { - // Don't use this._parseAddons() so that, for example, - // incompatible add-ons are not filtered out - let results = []; - for (let i = 0; i < aElements.length && results.length < this._maxResults; i++) { - let result = this._parseAddon(aElements[i], null, aCompatData); - if (result == null) - continue; + if (typeof aEntry.ratings == "object") { + addon.averageRating = Math.min(5, aEntry.ratings.average); + addon.reviewCount = aEntry.ratings.count; + } - // Ignore add-on if it wasn't actually requested - let idIndex = ids.indexOf(result.addon.id); - if (idIndex == -1) - continue; + addon.reviewURL = aEntry.ratings_url; + if (aEntry.last_updated) { + addon.updateDate = new Date(aEntry.last_updated); + } - // Ignore add-on if the add-on manager doesn't know about its type: - if (!(result.addon.type in AddonManager.addonTypes)) { - continue; - } + addon.icons = aEntry.icons || {}; - results.push(result); - // Ignore this add-on from now on - ids.splice(idIndex, 1); - } - - // Include any compatibility overrides for addons not hosted by the - // remote repository. - for (let id in aCompatData) { - let addonCompat = aCompatData[id]; - if (addonCompat.hosted) - continue; - - let addon = new AddonSearchResult(addonCompat.id); - // Compatibility overrides can only be for extensions. - addon.type = "extension"; - addon.compatibilityOverrides = addonCompat.compatRanges; - let result = { - addon, - xpiURL: null, - xpiHash: null - }; - results.push(result); - } - - // aTotalResults irrelevant - this._reportSuccess(results, -1); - }; - - this._beginSearch(url, ids.length, aCallback, handleResults, aTimeout); - }, - - /** - * Performs the daily background update check. - * - * This API both searches for the add-on IDs specified and sends performance - * data. It is meant to be called as part of the daily update ping. It should - * not be used for any other purpose. Use repopulateCache instead. - * - * @return Promise{null} Resolves when the metadata update is complete. - */ - backgroundUpdateCheck() { - return this._repopulateCacheInternal(true); - }, - - // Posts results to the callback - _reportSuccess(aResults, aTotalResults) { - this._searching = false; - this._request = null; - // The callback may want to trigger a new search so clear references early - let addons = aResults.map(result => result.addon); - let callback = this._callback; - this._callback = null; - callback.searchSucceeded(addons, addons.length, aTotalResults); - }, - - // Notifies the callback of a failure - _reportFailure() { - this._searching = false; - this._request = null; - // The callback may want to trigger a new search so clear references early - let callback = this._callback; - this._callback = null; - callback.searchFailed(); - }, - - // Get descendant by unique tag name. Returns null if not unique tag name. - _getUniqueDescendant(aElement, aTagName) { - let elementsList = aElement.getElementsByTagName(aTagName); - return (elementsList.length == 1) ? elementsList[0] : null; - }, - - // Get direct descendant by unique tag name. - // Returns null if not unique tag name. - _getUniqueDirectDescendant(aElement, aTagName) { - let elementsList = Array.filter(aElement.children, - aChild => aChild.tagName == aTagName); - return (elementsList.length == 1) ? elementsList[0] : null; - }, - - // Parse out trimmed text content. Returns null if text content empty. - _getTextContent(aElement) { - let textContent = aElement.textContent.trim(); - return (textContent.length > 0) ? textContent : null; - }, - - // Parse out trimmed text content of a descendant with the specified tag name - // Returns null if the parsing unsuccessful. - _getDescendantTextContent(aElement, aTagName) { - let descendant = this._getUniqueDescendant(aElement, aTagName); - return (descendant != null) ? this._getTextContent(descendant) : null; - }, - - // Parse out trimmed text content of a direct descendant with the specified - // tag name. - // Returns null if the parsing unsuccessful. - _getDirectDescendantTextContent(aElement, aTagName) { - let descendant = this._getUniqueDirectDescendant(aElement, aTagName); - return (descendant != null) ? this._getTextContent(descendant) : null; + return addon; }, /* - * Creates an AddonSearchResult by parsing an element + * Creates an AddonCompatibilityOverride by parsing an entry from the AMO API. * - * @param aElement - * The element to parse - * @param aSkip - * Object containing ids and sourceURIs of add-ons to skip. - * @param aCompatData - * Array of parsed addon_compatibility elements to accosiate with the - * resulting AddonSearchResult. Optional. - * @return Result object containing the parsed AddonSearchResult, xpiURL and - * xpiHash if the parsing was successful. Otherwise returns null. + * @param aEntry + * An entry from the AMO compat overrides API to parse. + * @return Result object containing the parsed AddonCompatibilityOverride */ - _parseAddon(aElement, aSkip, aCompatData) { - let skipIDs = (aSkip && aSkip.ids) ? aSkip.ids : []; - let skipSourceURIs = (aSkip && aSkip.sourceURIs) ? aSkip.sourceURIs : []; - - let guid = this._getDescendantTextContent(aElement, "guid"); - if (guid == null || skipIDs.includes(guid)) - return null; - - let addon = new AddonSearchResult(guid); - let result = { - addon, - xpiURL: null, - xpiHash: null + _parseCompatEntry(aEntry) { + let compat = { + id: aEntry.addon_guid, + compatRanges: null, }; - if (aCompatData && guid in aCompatData) - addon.compatibilityOverrides = aCompatData[guid].compatRanges; - - for (let node = aElement.firstChild; node; node = node.nextSibling) { - if (!(node instanceof Ci.nsIDOMElement)) - continue; - - let localName = node.localName; - - // Handle case where the wanted string value is located in text content - // but only if the content is not empty - if (localName in STRING_KEY_MAP) { - addon[STRING_KEY_MAP[localName]] = this._getTextContent(node) || addon[STRING_KEY_MAP[localName]]; - continue; - } - - // Handle case where the wanted string value is html located in text content - if (localName in HTML_KEY_MAP) { - addon[HTML_KEY_MAP[localName]] = convertHTMLToPlainText(this._getTextContent(node)); - continue; - } - - // Handle case where the wanted integer value is located in text content - if (localName in INTEGER_KEY_MAP) { - let value = parseInt(this._getTextContent(node)); - if (value >= 0) - addon[INTEGER_KEY_MAP[localName]] = value; - continue; - } - - // Handle cases that aren't as simple as grabbing the text content - switch (localName) { - case "type": - // Map AMO's type id to corresponding string - // https://github.com/mozilla/olympia/blob/master/apps/constants/base.py#L127 - // These definitions need to be updated whenever AMO adds a new type. - let id = parseInt(node.getAttribute("id")); - switch (id) { - case 1: - addon.type = "extension"; - break; - case 2: - addon.type = "theme"; - break; - case 3: - addon.type = "dictionary"; - break; - case 4: - addon.type = "search"; - break; - case 5: - case 6: - addon.type = "locale"; - break; - case 7: - addon.type = "plugin"; - break; - case 8: - addon.type = "api"; - break; - case 9: - addon.type = "lightweight-theme"; - break; - case 11: - addon.type = "webapp"; - break; - default: - logger.info("Unknown type id " + id + " found when parsing response for GUID " + guid); - } - break; - case "authors": - let authorNodes = node.getElementsByTagName("author"); - for (let authorNode of authorNodes) { - let name = this._getDescendantTextContent(authorNode, "name"); - let link = this._getDescendantTextContent(authorNode, "link"); - if (name == null || link == null) - continue; - - let author = new AddonManagerPrivate.AddonAuthor(name, link); - if (addon.creator == null) - addon.creator = author; - else { - if (addon.developers == null) - addon.developers = []; - - addon.developers.push(author); - } - } - break; - case "previews": - let previewNodes = node.getElementsByTagName("preview"); - for (let previewNode of previewNodes) { - let full = this._getUniqueDescendant(previewNode, "full"); - if (full == null) - continue; - - let fullURL = this._getTextContent(full); - let fullWidth = full.getAttribute("width"); - let fullHeight = full.getAttribute("height"); - - let thumbnailURL, thumbnailWidth, thumbnailHeight; - let thumbnail = this._getUniqueDescendant(previewNode, "thumbnail"); - if (thumbnail) { - thumbnailURL = this._getTextContent(thumbnail); - thumbnailWidth = thumbnail.getAttribute("width"); - thumbnailHeight = thumbnail.getAttribute("height"); - } - let caption = this._getDescendantTextContent(previewNode, "caption"); - let screenshot = new AddonManagerPrivate.AddonScreenshot(fullURL, fullWidth, fullHeight, - thumbnailURL, thumbnailWidth, - thumbnailHeight, caption); - - if (addon.screenshots == null) - addon.screenshots = []; - - if (previewNode.getAttribute("primary") == 1) - addon.screenshots.unshift(screenshot); - else - addon.screenshots.push(screenshot); - } - break; - case "learnmore": - addon.learnmoreURL = this._getTextContent(node); - addon.homepageURL = addon.homepageURL || addon.learnmoreURL; - break; - case "contribution_data": - let meetDevelopers = this._getDescendantTextContent(node, "meet_developers"); - let suggestedAmount = this._getDescendantTextContent(node, "suggested_amount"); - if (meetDevelopers != null) { - addon.contributionURL = meetDevelopers; - addon.contributionAmount = suggestedAmount; - } - break; - case "payment_data": - let link = this._getDescendantTextContent(node, "link"); - let amountTag = this._getUniqueDescendant(node, "amount"); - let amount = parseFloat(amountTag.getAttribute("amount")); - let displayAmount = this._getTextContent(amountTag); - if (link != null && amount != null && displayAmount != null) { - addon.purchaseURL = link; - addon.purchaseAmount = amount; - addon.purchaseDisplayAmount = displayAmount; - } - break; - case "rating": - let averageRating = parseInt(this._getTextContent(node)); - if (averageRating >= 0) - addon.averageRating = Math.min(5, averageRating); - break; - case "reviews": - let url = this._getTextContent(node); - let num = parseInt(node.getAttribute("num")); - if (url != null && num >= 0) { - addon.reviewURL = url; - addon.reviewCount = num; - } - break; - case "status": - let repositoryStatus = parseInt(node.getAttribute("id")); - if (!isNaN(repositoryStatus)) - addon.repositoryStatus = repositoryStatus; - break; - case "all_compatible_os": - let nodes = node.getElementsByTagName("os"); - addon.isPlatformCompatible = Array.some(nodes, function(aNode) { - let text = aNode.textContent.toLowerCase().trim(); - return text == "all" || text == Services.appinfo.OS.toLowerCase(); - }); - break; - case "install": - // No os attribute means the xpi is compatible with any os - if (node.hasAttribute("os")) { - let os = node.getAttribute("os").trim().toLowerCase(); - // If the os is not ALL and not the current OS then ignore this xpi - if (os != "all" && os != Services.appinfo.OS.toLowerCase()) - break; - } - - let xpiURL = this._getTextContent(node); - if (xpiURL == null) - break; - - if (skipSourceURIs.includes(xpiURL)) - return null; - - result.xpiURL = xpiURL; - addon.sourceURI = NetUtil.newURI(xpiURL); - - let size = parseInt(node.getAttribute("size")); - addon.size = (size >= 0) ? size : null; - - let xpiHash = node.getAttribute("hash"); - if (xpiHash != null) - xpiHash = xpiHash.trim(); - result.xpiHash = xpiHash ? xpiHash : null; - break; - case "last_updated": - let epoch = parseInt(node.getAttribute("epoch")); - if (!isNaN(epoch)) - addon.updateDate = new Date(1000 * epoch); - break; - case "icon": - addon.icons[node.getAttribute("size")] = this._getTextContent(node); - break; - } - } - - return result; - }, - - _parseAddons(aElements, aTotalResults, aSkip) { - let results = []; - - let isSameApplication = aAppNode => this._getTextContent(aAppNode) == Services.appinfo.ID; - - for (let i = 0; i < aElements.length && results.length < this._maxResults; i++) { - let element = aElements[i]; - - let tags = this._getUniqueDescendant(element, "compatible_applications"); - if (tags == null) - continue; - - let applications = tags.getElementsByTagName("appID"); - let compatible = Array.some(applications, aAppNode => { - if (!isSameApplication(aAppNode)) - return false; - - let parent = aAppNode.parentNode; - let minVersion = this._getDescendantTextContent(parent, "min_version"); - let maxVersion = this._getDescendantTextContent(parent, "max_version"); - if (minVersion == null || maxVersion == null) - return false; - - let currentVersion = Services.appinfo.version; - return (Services.vc.compare(minVersion, currentVersion) <= 0 && - ((!AddonManager.strictCompatibility) || - Services.vc.compare(currentVersion, maxVersion) <= 0)); - }); - - // Ignore add-ons not compatible with this Application - if (!compatible) { - if (AddonManager.checkCompatibility) - continue; - - if (!Array.some(applications, isSameApplication)) - continue; - } - - // Add-on meets all requirements, so parse out data. - // Don't pass in compatiblity override data, because that's only returned - // in GUID searches, which don't use _parseAddons(). - let result = this._parseAddon(element, aSkip); - if (result == null) - continue; - - // Ignore add-on missing a required attribute - let requiredAttributes = ["id", "name", "version", "type", "creator"]; - if (requiredAttributes.some(aAttribute => !result.addon[aAttribute])) - continue; - - // Ignore add-on with a type AddonManager doesn't understand: - if (!(result.addon.type in AddonManager.addonTypes)) - continue; - - // Add only if the add-on is compatible with the platform - if (!result.addon.isPlatformCompatible) - continue; - - // Add only if there was an xpi compatible with this OS or there was a - // way to purchase the add-on - if (!result.xpiURL && !result.addon.purchaseURL) - continue; - - result.addon.isCompatible = compatible; - - results.push(result); - // Ignore this add-on from now on by adding it to the skip array - aSkip.ids.push(result.addon.id); - } - - // Immediately report success if no AddonInstall instances to create - let pendingResults = results.length; - if (pendingResults == 0) { - this._reportSuccess(results, aTotalResults); - return; - } - - // Create an AddonInstall for each result - for (let result of results) { - let addon = result.addon; - let callback = aInstall => { - addon.install = aInstall; - pendingResults--; - if (pendingResults == 0) - this._reportSuccess(results, aTotalResults); - }; - - if (result.xpiURL) { - AddonManager.getInstallForURL(result.xpiURL, callback, - "application/x-xpinstall", result.xpiHash, - addon.name, addon.icons, addon.version); - } else { - callback(null); - } - } - }, - - // Parses addon_compatibility nodes, that describe compatibility overrides. - _parseAddonCompatElement(aResultObj, aElement) { - let guid = this._getDescendantTextContent(aElement, "guid"); - if (!guid) { - logger.debug("Compatibility override is missing guid."); - return; - } - - let compat = {id: guid}; - compat.hosted = aElement.getAttribute("hosted") != "false"; - - function findMatchingAppRange(aNodes) { - let toolkitAppRange = null; - for (let node of aNodes) { - let appID = this._getDescendantTextContent(node, "appID"); - if (appID != Services.appinfo.ID && appID != TOOLKIT_ID) - continue; - - let minVersion = this._getDescendantTextContent(node, "min_version"); - let maxVersion = this._getDescendantTextContent(node, "max_version"); - if (minVersion == null || maxVersion == null) - continue; - - let appRange = { appID, - appMinVersion: minVersion, - appMaxVersion: maxVersion }; - - // Only use Toolkit app ranges if no ranges match the application ID. - if (appID == TOOLKIT_ID) - toolkitAppRange = appRange; - else - return appRange; - } - return toolkitAppRange; - } - - function parseRangeNode(aNode) { - let type = aNode.getAttribute("type"); - // Only "incompatible" (blacklisting) is supported for now. - if (type != "incompatible") { - logger.debug("Compatibility override of unsupported type found."); - return null; - } - - let override = new AddonManagerPrivate.AddonCompatibilityOverride(type); - - override.minVersion = this._getDirectDescendantTextContent(aNode, "min_version"); - override.maxVersion = this._getDirectDescendantTextContent(aNode, "max_version"); - - if (!override.minVersion) { + for (let range of aEntry.version_ranges) { + if (!range.addon_min_version) { logger.debug("Compatibility override is missing min_version."); - return null; + continue; } - if (!override.maxVersion) { + if (!range.addon_max_version) { logger.debug("Compatibility override is missing max_version."); return null; } - let appRanges = aNode.querySelectorAll("compatible_applications > application"); - let appRange = findMatchingAppRange.bind(this)(appRanges); - if (!appRange) { + let override = new AddonManagerPrivate.AddonCompatibilityOverride("incompatible"); + override.minVersion = range.addon_min_version; + override.maxVersion = range.addon_max_version; + + for (let app of range.applications) { + if (app.guid != Services.appinfo.ID && app.guid != TOOLKIT_ID) { + continue; + } + if (!app.min_version || !app.max_version) { + continue; + } + + override.appID = app.guid; + override.appMinVersion = app.min_version; + override.appMaxVersion = app.max_version; + if (app.id != TOOLKIT_ID) { + break; + } + } + + if (!override.appID) { logger.debug("Compatibility override is missing a valid application range."); - return null; + continue; } - override.appID = appRange.appID; - override.appMinVersion = appRange.appMinVersion; - override.appMaxVersion = appRange.appMaxVersion; - - return override; - } - - let rangeNodes = aElement.querySelectorAll("version_ranges > version_range"); - compat.compatRanges = Array.map(rangeNodes, parseRangeNode.bind(this)) - .filter(aItem => !!aItem); - if (compat.compatRanges.length == 0) - return; - - aResultObj[compat.id] = compat; - }, - - // Parses addon_compatibility elements. - _parseAddonCompatData(aElements) { - let compatData = {}; - Array.forEach(aElements, this._parseAddonCompatElement.bind(this, compatData)); - return compatData; - }, - - // Begins a new search if one isn't currently executing - _beginSearch(aURI, aMaxResults, aCallback, aHandleResults, aTimeout) { - if (this._searching || aURI == null || aMaxResults <= 0) { - logger.warn("AddonRepository search failed: searching " + this._searching + " aURI " + aURI + - " aMaxResults " + aMaxResults); - aCallback.searchFailed(); - return; - } - - this._searching = true; - this._callback = aCallback; - this._maxResults = aMaxResults; - - logger.debug("Requesting " + aURI); - - this._request = new ServiceRequest(); - this._request.mozBackgroundRequest = true; - this._request.open("GET", aURI, true); - this._request.overrideMimeType("text/xml"); - if (aTimeout) { - this._request.timeout = aTimeout; - } - - this._request.addEventListener("error", aEvent => this._reportFailure()); - this._request.addEventListener("timeout", aEvent => this._reportFailure()); - this._request.addEventListener("load", aEvent => { - logger.debug("Got metadata search load event"); - let request = aEvent.target; - let responseXML = request.responseXML; - - if (!responseXML || responseXML.documentElement.namespaceURI == XMLURI_PARSE_ERROR || - (request.status != 200 && request.status != 0)) { - this._reportFailure(); - return; + if (compat.compatRanges === null) { + compat.compatRanges = []; } + compat.compatRanges.push(override); + } - let documentElement = responseXML.documentElement; - let elements = documentElement.getElementsByTagName("addon"); - let totalResults = elements.length; - let parsedTotalResults = parseInt(documentElement.getAttribute("total_results")); - // Parsed value of total results only makes sense if >= elements.length - if (parsedTotalResults >= totalResults) - totalResults = parsedTotalResults; - - let compatElements = documentElement.getElementsByTagName("addon_compatibility"); - let compatData = this._parseAddonCompatData(compatElements); - - aHandleResults(elements, totalResults, compatData); - }); - this._request.send(null); + return compat; }, // Create url from preference, returning null if preference does not exist @@ -1292,7 +726,8 @@ var AddonRepository = { } url = url.replace(/%([A-Z_]+)%/g, function(aMatch, aKey) { - return (aKey in aSubstitutions) ? aSubstitutions[aKey] : aMatch; + return (aKey in aSubstitutions) ? encodeURIComponent(aSubstitutions[aKey]) + : aMatch; }); return Services.urlFormatter.formatURL(url); @@ -1301,11 +736,10 @@ var AddonRepository = { // Find a AddonCompatibilityOverride that matches a given aAddonVersion and // application/platform version. findMatchingCompatOverride(aAddonVersion, - aCompatOverrides, - aAppVersion, - aPlatformVersion) { + aCompatOverrides, + aAppVersion, + aPlatformVersion) { for (let override of aCompatOverrides) { - let appVersion = null; if (override.appID == TOOLKIT_ID) appVersion = aPlatformVersion || Services.appinfo.platformVersion; @@ -1324,11 +758,12 @@ var AddonRepository = { flush() { return AddonDatabase.flush(); - } + }, }; var AddonDatabase = { connectionPromise: null, + _loaded: false, _saveTask: null, _blockerAdded: false, @@ -1340,7 +775,7 @@ var AddonDatabase = { */ get jsonFile() { return OS.Path.join(OS.Constants.Path.profileDir, FILE_DATABASE); - }, + }, /** * Asynchronously opens a new connection to the database file. @@ -1349,9 +784,7 @@ var AddonDatabase = { */ openConnection() { if (!this.connectionPromise) { - this.connectionPromise = (async () => { - this.DB = BLANK_DB(); - + this.connectionPromise = (async () => { let inputDB, schema; try { @@ -1384,18 +817,32 @@ var AddonDatabase = { this.save(); Services.prefs.setIntPref(PREF_GETADDONS_DB_SCHEMA, DB_SCHEMA); + this._loaded = true; return this.DB; } Services.prefs.setIntPref(PREF_GETADDONS_DB_SCHEMA, DB_SCHEMA); - // We use _insertAddon manually instead of calling - // insertAddons to avoid the write to disk which would - // be a waste since this is the data that was just read. + // Convert the addon and compat override objects as necessary + // and store them in our in-memory copy of the database. for (let addon of inputDB.addons) { - this._insertAddon(addon); + let id = addon.id; + + let entry = this._parseAddon(addon); + this.DB.addons.set(id, entry); + + if (entry.compatibilityOverrides) { + this.DB.compatOverrides.set(id, entry.compatibilityOverrides); + } } + if (inputDB.compatOverrides) { + for (let entry of inputDB.compatOverrides) { + this.DB.compatOverrides.set(entry.id, entry.compatRanges); + } + } + + this._loaded = true; return this.DB; })(); } @@ -1419,6 +866,7 @@ var AddonDatabase = { } this.connectionPromise = null; + this._loaded = false; if (aSkipFlush || !this._saveTask) { return Promise.resolve(); @@ -1452,17 +900,20 @@ var AddonDatabase = { this.jsonFile, error)) .then(() => this._deleting = null) .then(aCallback); + return this._deleting; }, async _saveNow() { let json = { schema: this.DB.schema, - addons: [] + addons: Array.from(this.DB.addons.values()), + compatOverrides: [], }; - for (let [, value] of this.DB.addons) - json.addons.push(value); + for (let [id, overrides] of this.DB.compatOverrides.entries()) { + json.compatOverrides.push({id, compatRanges: overrides}); + } await OS.File.writeAtomic(this.jsonFile, JSON.stringify(json), {tmpPath: `${this.jsonFile}.tmp`}); @@ -1509,71 +960,79 @@ var AddonDatabase = { }, /** - * Asynchronously retrieve all add-ons from the database - * @return: Promise{Map} - * Resolves when the add-ons are retrieved from the database + * Get an individual addon entry from the in-memory cache. + * Note: calling this function before the database is read will + * return undefined. + * + * @param {string} aId The id of the addon to retrieve. */ - retrieveStoredData() { - return this.openConnection().then(db => db.addons); + getAddon(aId) { + return this.DB.addons.get(aId); + }, + + /** + * Get an individual compatibility override from the in-memory cache. + * Note: calling this function before the database is read will + * return undefined. + * + * @param {string} aId The id of the addon to retrieve. + */ + getCompatOverrides(aId) { + return this.DB.compatOverrides.get(aId); }, /** * Asynchronously repopulates the database so it only contains the * specified add-ons * - * @param aAddons - * The array of add-ons to repopulate the database with - * @param aCallback - * An optional callback to call once complete + * @param {Map} aAddons + * Add-ons to repopulate the database with. + * @param {Map} aCompatOverrides + * Compatibility overrides to repopulate the database with. */ - repopulate(aAddons, aCallback) { - this.DB.addons.clear(); - this.insertAddons(aAddons, function() { - let now = Math.round(Date.now() / 1000); - logger.debug("Cache repopulated, setting " + PREF_METADATA_LASTUPDATE + " to " + now); - Services.prefs.setIntPref(PREF_METADATA_LASTUPDATE, now); - if (aCallback) - aCallback(); - }); + repopulate(aAddons, aCompatOverrides) { + this.DB = BLANK_DB(); + this._update(aAddons, aCompatOverrides); + + let now = Math.round(Date.now() / 1000); + logger.debug("Cache repopulated, setting " + PREF_METADATA_LASTUPDATE + " to " + now); + Services.prefs.setIntPref(PREF_METADATA_LASTUPDATE, now); }, /** - * Asynchronously inserts an array of add-ons into the database + * Asynchronously insert new addons and/or overrides into the database. * - * @param aAddons - * The array of add-ons to insert - * @param aCallback - * An optional callback to call once complete + * @param {Map} aAddons + * Add-ons to insert/update in the database + * @param {Map} aCompatOverrides + * Compatibility overrides to insert/update in the database */ - async insertAddons(aAddons, aCallback) { + async update(aAddons, aCompatOverrides) { await this.openConnection(); + this._update(aAddons, aCompatOverrides); + + this.save(); + }, + + /** + * Merge the given addons and overrides into the database. + * + * @param {Map} aAddons + * Add-ons to insert/update in the database + * @param {Map} aCompatOverrides + * Compatibility overrides to insert/update in the database + */ + _update(aAddons, aCompatOverrides) { for (let addon of aAddons) { - this._insertAddon(addon); + this.DB.addons.set(addon.id, this._parseAddon(addon)); + } + + for (let entry of aCompatOverrides) { + this.DB.compatOverrides.set(entry.id, entry.compatRanges); } this.save(); - aCallback && aCallback(); - }, - - /** - * Inserts an individual add-on into the database. If the add-on already - * exists in the database (by id), then the specified add-on will not be - * inserted. - * - * @param aAddon - * The add-on to insert into the database - * @param aCallback - * The callback to call once complete - */ - _insertAddon(aAddon) { - let newAddon = this._parseAddon(aAddon); - if (!newAddon || - !newAddon.id || - this.DB.addons.has(newAddon.id)) - return; - - this.DB.addons.set(newAddon.id, newAddon); }, /* @@ -1631,15 +1090,6 @@ var AddonDatabase = { } break; - case "compatibilityOverrides": - if (!addon.compatibilityOverrides) addon.compatibilityOverrides = []; - for (let override of value) { - addon.compatibilityOverrides.push( - this._makeCompatOverride(override) - ); - } - break; - case "icons": if (!addon.icons) addon.icons = {}; for (let size of Object.keys(aObj.icons)) { @@ -1721,27 +1171,4 @@ var AddonDatabase = { return new AddonManagerPrivate.AddonScreenshot(url, width, height, thumbnailURL, thumbnailWidth, thumbnailHeight, caption); }, - - /** - * Make a CompatibilityOverride from a vanilla - * JS object from the JSON database - * - * @param aObj - * The JS object to use - * @return The created CompatibilityOverride - */ - _makeCompatOverride(aObj) { - let type = aObj.type; - let minVersion = aObj.minVersion; - let maxVersion = aObj.maxVersion; - let appID = aObj.appID; - let appMinVersion = aObj.appMinVersion; - let appMaxVersion = aObj.appMaxVersion; - return new AddonManagerPrivate.AddonCompatibilityOverride(type, - minVersion, - maxVersion, - appID, - appMinVersion, - appMaxVersion); - }, }; diff --git a/toolkit/mozapps/extensions/internal/XPIInstall.jsm b/toolkit/mozapps/extensions/internal/XPIInstall.jsm index fbc92233efe3..08f0fa74e318 100644 --- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm +++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm @@ -1622,12 +1622,15 @@ class AddonInstall { // makes it impossible to delete on Windows. // Try to load from the existing cache first - let repoAddon = await new Promise(resolve => AddonRepository.getCachedAddonByID(this.addon.id, resolve)); + let repoAddon = await AddonRepository.getCachedAddonByID(this.addon.id); // It wasn't there so try to re-download it if (!repoAddon) { - await new Promise(resolve => AddonRepository.cacheAddons([this.addon.id], resolve)); - repoAddon = await new Promise(resolve => AddonRepository.getCachedAddonByID(this.addon.id, resolve)); + try { + [repoAddon] = await AddonRepository.cacheAddons([this.addon.id]); + } catch (err) { + logger.debug(`Error getting metadata for ${this.addon.id}: ${err.message}`); + } } this.addon._repositoryAddon = repoAddon; diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index 9e1f81b85e6b..5945ef853441 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -3934,8 +3934,8 @@ var XPIProvider = { } for (let addon of aAddons) { - AddonRepository.getCachedAddonByID(addon.id, aRepoAddon => { - if (aRepoAddon) { + AddonRepository.getCachedAddonByID(addon.id).then(aRepoAddon => { + if (aRepoAddon || AddonRepository.getCompatibilityOverridesSync(addon.id)) { logger.debug("updateAddonRepositoryData got info for " + addon.id); addon._repositoryAddon = aRepoAddon; this.updateAddonDisabledState(addon); @@ -5756,7 +5756,7 @@ function defineAddonWrapperProperty(name, getter) { ["fullDescription", "developerComments", "supportURL", "contributionURL", "averageRating", "reviewCount", - "reviewURL"].forEach(function(aProp) { + "reviewURL", "weeklyDownloads"].forEach(function(aProp) { defineAddonWrapperProperty(aProp, function() { let addon = addonFor(this); if (addon._repositoryAddon) diff --git a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js index ed7dfb093f69..89fb8c3514f0 100644 --- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js +++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js @@ -76,11 +76,10 @@ function getRepositoryAddon(aAddon, aCallback) { aCallback(aAddon); return; } - function completeAddon(aRepositoryAddon) { - aAddon._repositoryAddon = aRepositoryAddon; + AddonRepository.getCachedAddonByID(aAddon.id, repoAddon => { + aAddon._repositoryAddon = repoAddon; aCallback(aAddon); - } - AddonRepository.getCachedAddonByID(aAddon.id, completeAddon); + }); } /** diff --git a/toolkit/mozapps/extensions/test/browser/browser.ini b/toolkit/mozapps/extensions/test/browser/browser.ini index 08ae271f2fa3..9567662b5e85 100644 --- a/toolkit/mozapps/extensions/test/browser/browser.ini +++ b/toolkit/mozapps/extensions/test/browser/browser.ini @@ -38,7 +38,6 @@ tags = blocklist skip-if = buildapp == 'mulet' [browser_about.js] skip-if = os == 'linux' || os == 'win' # bug 632290 -[browser_addonrepository_performance.js] [browser_bug523784.js] [browser_bug562797.js] [browser_bug562854.js] diff --git a/toolkit/mozapps/extensions/test/browser/browser_addonrepository_performance.js b/toolkit/mozapps/extensions/test/browser/browser_addonrepository_performance.js deleted file mode 100644 index 9d680eea418c..000000000000 --- a/toolkit/mozapps/extensions/test/browser/browser_addonrepository_performance.js +++ /dev/null @@ -1,96 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ - */ - -// Tests that the metadata request includes startup time measurements - -var tmp = {}; -ChromeUtils.import("resource://gre/modules/addons/AddonRepository.jsm", tmp); -var AddonRepository = tmp.AddonRepository; - -var gProvider; - -function parseParams(aQuery) { - let params = {}; - - for (let param of aQuery.split("&")) { - let [key, value] = param.split("="); - params[key] = value; - } - - return params; -} - -function test() { - waitForExplicitFinish(); - - var gSeenRequest = false; - - gProvider = new MockProvider(); - gProvider.createAddons([{ - id: "test1@tests.mozilla.org", - name: "Test add-on" - }]); - - function observe(aSubject, aTopic, aData) { - aSubject.QueryInterface(Ci.nsIChannel); - let url = aSubject.URI.QueryInterface(Ci.nsIURL); - if (url.filePath != "/extensions-dummy/metadata") { - return; - } - info(url.query); - - // Check if we encountered telemetry errors and turn the tests for which - // we don't have valid data into known failures. - let snapshot = Services.telemetry.getHistogramById("STARTUP_MEASUREMENT_ERRORS") - .snapshot(); - - let tProcessValid = (snapshot.counts[0] == 0); - let tMainValid = tProcessValid && (snapshot.counts[2] == 0); - let tFirstPaintValid = tProcessValid && (snapshot.counts[5] == 0); - let tSessionRestoredValid = tProcessValid && (snapshot.counts[6] == 0); - - let params = parseParams(url.query); - - is(params.appOS, Services.appinfo.OS, "OS should be correct"); - is(params.appVersion, Services.appinfo.version, "Version should be correct"); - - if (tMainValid) { - ok(params.tMain >= 0, "Should be a sensible tMain"); - } else { - todo(false, "An error occurred while recording the startup timestamps, skipping this test"); - } - - if (tFirstPaintValid) { - ok(params.tFirstPaint >= 0, "Should be a sensible tFirstPaint"); - } else { - todo(false, "An error occurred while recording the startup timestamps, skipping this test"); - } - - if (tSessionRestoredValid) { - ok(params.tSessionRestored >= 0, "Should be a sensible tSessionRestored"); - } else { - todo(false, "An error occurred while recording the startup timestamps, skipping this test"); - } - - gSeenRequest = true; - } - - const PREF = "extensions.getAddons.getWithPerformance.url"; - - // Watch HTTP requests - Services.obs.addObserver(observe, "http-on-modify-request"); - Services.prefs.setCharPref(PREF, - "http://127.0.0.1:8888/extensions-dummy/metadata?appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%"); - - registerCleanupFunction(function() { - Services.obs.removeObserver(observe, "http-on-modify-request"); - }); - - AddonRepository._beginGetAddons(["test1@tests.mozilla.org"], { - searchFailed() { - ok(gSeenRequest, "Should have seen metadata request"); - finish(); - } - }, true); -} diff --git a/toolkit/mozapps/extensions/test/browser/browser_discovery_install.js b/toolkit/mozapps/extensions/test/browser/browser_discovery_install.js index ac4a71291052..9d9208768a00 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_discovery_install.js +++ b/toolkit/mozapps/extensions/test/browser/browser_discovery_install.js @@ -12,8 +12,6 @@ const BAD_FRAMED_URL = "https://example.org/" + RELATIVE_DIR + "discovery_frame. const PREF_INSTALL_REQUIREBUILTINCERTS = "extensions.install.requireBuiltInCerts"; -// Temporarily enable caching -Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); // Allow SSL from non-built-in certs Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false); // Allow installs from the test site diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository.xml deleted file mode 100644 index 0bebca2c1aec..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository.xml +++ /dev/null @@ -1,820 +0,0 @@ - - - - - PASS - Extension - test1@tests.mozilla.org - 1.1 - - - Test Creator 1 - http://localhost:%PORT%/creator1.html - - - Preliminarily Reviewed - - - xpcshell@tests.mozilla.org - 1 - 1 - - - - -2 - - - - -2 - http://localhost:%PORT%/test1.xpi - - - - - PASS - - Extension - test2@tests.mozilla.org - 1.2 - - - - Test Creator 2 - http://localhost:%PORT%/creator2.html - - - Test Developer 2 - http://localhost:%PORT%/developer2.html - - - <h1>Test Summary 2</h1><p>paragraph</p> - Test Description 2<br>newline - Test Developer - Comments 2 - Test EULA 2 - http://localhost:%PORT%/icon2-64.png - http://localhost:%PORT%/icon2-48.png - http://localhost:%PORT%/icon2-32.png - Public - - - xpcshell@tests.mozilla.org - 1 - 1 - - - - - - http://localhost:%PORT%/full1-2.png - http://localhost:%PORT%/thumbnail1-2.png - - - http://localhost:%PORT%/full2-2.png - http://localhost:%PORT%/thumbnail2-2.png - Caption 2 - - - NaN - - http://localhost:%PORT%/learnmore2.html - - http://localhost:%PORT%/support2.html - - http://localhost:%PORT%/contribution2.html - http://localhost:%PORT%/meetDevelopers2.html - - http://localhost:%PORT%/review2.html - NaN - NaN - NaN - Not an acual date - http://localhost:%PORT%/test2.xpi - - - - - PASS - - Theme - test3@tests.mozilla.org - 1.3 - - - - - http://localhost:%PORT%/ignore3.html - - - - Test Creator Ignore - - - - Test Creator 3 - http://localhost:%PORT%/creator3.html - - - First Test Developer 3 - http://localhost:%PORT%/developer1-3.html - - - - - - - Second Test Developer 3 - http://localhost:%PORT%/developer2-3.html - - - Test Summary 3 - Test Description 3<br><ul><li>List item 1<li>List item 2</ul> - Test Developer Comments 3 - Test EULA 3 - http://localhost:%PORT%/icon3.png - Preliminarily Reviewed - - - - unknown@tests.mozilla.org - 1 - 1 - - - xpcshell@tests.mozilla.org - 1 - 1 - - - - - - http://localhost:%PORT%/full2-3.png - Caption 2 - 3 - - - - Caption ignore - 3 - - - - - Caption ignore - 3 - - http://localhost:%PORT%/full1-3.png - http://localhost:%PORT%/thumbnail1-3.png - Caption 1 - 3 - - - http://localhost:%PORT%/full3-3.png - http://localhost:%PORT%/thumbnail3-3.png - Caption 3 - 3 - - - - - 2 - - http://localhost:%PORT%/learnmore3.html - http://localhost:%PORT%/homepage3.html - http://localhost:%PORT%/support3.html - - http://localhost:%PORT%/contribution3.html - $11.11 - http://localhost:%PORT%/meetDevelopers3.html - - http://localhost:%PORT%/review3.html - 2222 - 3333 - 4444 - 2010-02-01T14:04:05Z - - http://localhost:%PORT%/fail3.xpi - - http://localhost:%PORT%/test3.xpi - - - - - Extension - test4@tests.mozilla.org - 1.4 - Test Creator 4 - Public - Add-on with undefined name should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test4.xpi - - - - - - Extension - test5@tests.mozilla.org - 1.5 - Test Creator 5 - Public - Add-on with empty name should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test5.xpi - - - - - FAIL - test6@tests.mozilla.org - 1.6 - Test Creator 6 - Public - Add-on with undefined type should be ignored - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test6.xpi - - - - - FAIL - Empty id attribute - test7@tests.mozilla.org - 1.7 - Test Creator 7 - Public - Add-on with empty type should be ignored - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test7.xpi - - - - - FAIL - Unknown - test8@tests.mozilla.org - 1.8 - Test Creator 8 - Public - Add-on with unknown type should be ignored - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test8.xpi - - - - - FAIL - Extension - 1.9 - Test Creator 9 - Public - Add-on with undefined guid should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test9.xpi - - - - - FAIL - Extension - - 1.10 - Test Creator 10 - Public - Add-on with empty guid should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test10.xpi - - - - - FAIL - Extension - test1@tests.mozilla.org - 1.11 - Test Creator 11 - Public - Add-on with a guid that matches a previously successful result should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test11.xpi - - - - - FAIL - Extension - test_AddonRepository_1@tests.mozilla.org - 1.12 - Test Creator 12 - Public - Add-on with a guid that matches an installed Addon should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test12.xpi - - - - - FAIL - Extension - test13@tests.mozilla.org - Test Creator 13 - Public - Add-on with undefined version should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test13.xpi - - - - - FAIL - Extension - test14@tests.mozilla.org - - Test Creator 14 - Public - Add-on with empty version should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test14.xpi - - - - - FAIL - Extension - test15@tests.mozilla.org - 1.15 - Public - Add-on with undefined authors should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test15.xpi - - - - - FAIL - Extension - test16@tests.mozilla.org - 1.16 - - Public - Add-on with no defined author elements should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test16.xpi - - - - - FAIL - Extension - test17@tests.mozilla.org - 1.17 - - - - - Public - Add-on with no non-empty author elements should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test17.xpi - - - - - FAIL - Extension - test18@tests.mozilla.org - 1.18 - Test Creator 18 - Add-on with undefined status should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test18.xpi - - - - - FAIL - Extension - test19@tests.mozilla.org - 1.19 - Test Creator 19 - Unknown - Add-on with non-Public status should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test19.xpi - - - - - FAIL - Extension - test20@tests.mozilla.org - 1.20 - Test Creator 20 - Public - Add-on with undefined compatible_applications should be ignored. - http://localhost:%PORT%/test20.xpi - - - - - FAIL - Extension - test21@tests.mozilla.org - 1.21 - Test Creator 21 - Public - Add-on with no compatible applications should be ignored. - - - unknown@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test21.xpi - - - - - FAIL - Extension - test22@tests.mozilla.org - 1.22 - Test Creator 22 - Public - Add-on with too high of a compatible application min version should be ignored. - - - xpcshell@tests.mozilla.org - 2.0 - - - http://localhost:%PORT%/test22.xpi - - - - - FAIL - Extension - test23@tests.mozilla.org - 1.23 - Test Creator 23 - Public - Add-on with too high of a compatible application min version should be ignored. - - - xpcshell@tests.mozilla.org - 1.1 - 2.0 - - - http://localhost:%PORT%/test23.xpi - - - - - FAIL - Extension - test24@tests.mozilla.org - 1.24 - Test Creator 24 - Public - Add-on with too low of a compatible application max version should be ignored. - - - xpcshell@tests.mozilla.org - 0.9 - - - http://localhost:%PORT%/test24.xpi - - - - - FAIL - Extension - test25@tests.mozilla.org - 1.25 - Test Creator 25 - Public - Add-on with too low of a compatible application max version should be ignored. - - - xpcshell@tests.mozilla.org - 0.9 - 0.9.9 - - - http://localhost:%PORT%/test25.xpi - - - - - FAIL - Extension - test26@tests.mozilla.org - 1.26 - Test Creator 26 - Public - Add-on with undefined XPI URL should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - - - - - FAIL - Extension - test27@tests.mozilla.org - 1.27 - Test Creator 27 - Public - Add-on with an empty XPI URL should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - - - - - - FAIL - Extension - test28@tests.mozilla.org - 1.28 - Test Creator 28 - Public - Add-on with no installs with compatible OS should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test28.xpi - http://localhost:%PORT%/test28.xpi - - - - - FAIL - Extension - test29@tests.mozilla.org - 1.29 - Test Creator 29 - Public - Add-on with an XPI URL that matches an installing AddonInstall should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/addons/test_AddonRepository_2.xpi - - - - - PASS - Extension - purchase1@tests.mozilla.org - 2.0 - - - Test Creator - Last Passing - http://localhost:%PORT%/creatorLastPassing.html - - - Public - - ALL - - - - xpcshell@tests.mozilla.org - 1 - 1 - - - 5 - - http://localhost:%PORT%/purchaseURL1 - $5 - - - - - - PASS - Extension - purchase2@tests.mozilla.org - 2.0 - - - Test Creator - Last Passing - http://localhost:%PORT%/creatorLastPassing.html - - - Public - - XPCShell - - - - xpcshell@tests.mozilla.org - 1 - 1 - - - 5 - - http://localhost:%PORT%/purchaseURL2 - $10 - - - - - - FAIL - Extension - purchase3@tests.mozilla.org - 2.0 - - - Test Creator - Last Passing - http://localhost:%PORT%/creatorLastPassing.html - - - Public - - FOO - - - - xpcshell@tests.mozilla.org - 1 - 1 - - - 5 - - http://localhost:%PORT%/purchaseURL3 - $10 - - - - - - PASS - Extension - test-lastPassing@tests.mozilla.org - 2.0 - - - Test Creator - Last Passing - http://localhost:%PORT%/creatorLastPassing.html - - - Public - - - xpcshell@tests.mozilla.org - 1 - 1 - - - - 10 - http://localhost:%PORT%/addons/test_AddonRepository_3.xpi - - - - - FAIL - Extension - test-surpassesLimit@tests.mozilla.org - 9.9 - Test Creator - Surpasses Limit - Public - Add-on should not be added because doing so would surpass MAX_RESULTS limit - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test-surpassesLimit.xpi - - - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache.json new file mode 100644 index 000000000000..441a3cd57475 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache.json @@ -0,0 +1,132 @@ +{ + "page_size": 25, + "page_count": 1, + "count": 4, + "next": null, + "previous": null, + "results": [ + { + "name": "Repo Add-on 1", + "type": "extension", + "guid": "test_AddonRepository_1@tests.mozilla.org", + "current_version": { + "version": "2.1", + "files": [ + { + "platform": "all", + "size": 9, + "url": "http://localhost:4444/repo/1/install.xpi" + } + ] + }, + "authors": [ + { + "name": "Repo Add-on 1 - Creator", + "url": "http://localhost:4444/repo/1/creator.html" + }, + { + "name": "Repo Add-on 1 - First Developer", + "url": "http://localhost:4444/repo/1/firstDeveloper.html" + }, + { + "name": "Repo Add-on 1 - Second Developer", + "url": "http://localhost:4444/repo/1/secondDeveloper.html" + } + ], + "summary": "Repo Add-on 1 - Description
Second line", + "description": "

Repo Add-on 1 - Full Description & some extra

", + "icons": { + "32": "http://localhost/repo/1/icon.png" + }, + "ratings": { + "count": 1111, + "average": 1 + }, + "homepage": "http://localhost/repo/1/homepage.html", + "support_url": "http://localhost/repo/1/support.html", + "contributions_url": "http://localhost/repo/1/meetDevelopers.html", + "ratings_url": "http://localhost/repo/1/review.html", + "weekly_downloads": 3331, + "last_updated": "1970-01-01T00:00:09Z" + }, + { + "name": "Repo Add-on 2", + "type": "theme", + "guid": "test_AddonRepository_2@tests.mozilla.org", + "current_version": { + "version": "2.2", + "files": [ + { + "platform": "all", + "size": 9, + "url": "http://localhost:4444/repo/2/install.xpi" + } + ] + }, + "authors": [ + { + "name": "Repo Add-on 2 - Creator", + "url": "http://localhost:4444/repo/2/creator.html" + }, + { + "name": "Repo Add-on 2 - First Developer", + "url": "http://localhost:4444/repo/2/firstDeveloper.html" + }, + { + "name": "Repo Add-on 2 - Second Developer", + "url": "http://localhost:4444/repo/2/secondDeveloper.html" + } + ], + "summary": "Repo Add-on 2 - Description", + "description": "Repo Add-on 2 - Full Description", + "icons": { + "32": "http://localhost/repo/2/icon.png" + }, + "previews": [ + { + "image_url": "http://localhost:4444/repo/2/firstFull.png", + "thumbnail_url": "http://localhost:4444/repo/2/firstThumbnail.png", + "caption": "Repo Add-on 2 - First Caption" + }, + { + "image_url": "http://localhost:4444/repo/2/secondFull.png", + "thumbnail_url": "http://localhost:4444/repo/2/secondThumbnail.png", + "caption": "Repo Add-on 2 - Second Caption" + } + ], + "ratings": { + "count": 1112, + "average": 2 + }, + "homepage": "http://localhost/repo/2/homepage.html", + "support_url": "http://localhost/repo/2/support.html", + "contributions_url": "http://localhost/repo/2/meetDevelopers.html", + "ratings_url": "http://localhost/repo/2/review.html", + "weekly_downloads": 3332, + "last_updated": "1970-01-01T00:00:09Z" + }, + { + "name": "Repo Add-on 3", + "type": "theme", + "guid": "test_AddonRepository_3@tests.mozilla.org", + "current_version": { + "version": "2.3" + }, + "icons": { + "32": "http://localhost/repo/3/icon.png" + }, + "previews": [ + { + "image_url": "http://localhost:4444/repo/3/firstFull.png", + "thumbnail_url": "http://localhost:4444/repo/3/firstThumbnail.png", + "caption": "Repo Add-on 3 - First Caption" + }, + { + "image_url": "http://localhost:4444/repo/3/secondFull.png", + "thumbnail_url": "http://localhost:4444/repo/3/secondThumbnail.png", + "caption": "Repo Add-on 3 - Second Caption" + } + ] + } + ] +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache.xml deleted file mode 100644 index f707f1217d90..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache.xml +++ /dev/null @@ -1,182 +0,0 @@ - - - - Repo Add-on 1 - Extension - test_AddonRepository_1@tests.mozilla.org - 2.1 - - - Repo Add-on 1 - Creator - http://localhost:4444/repo/1/creator.html - - - Repo Add-on 1 - First Developer - http://localhost:4444/repo/1/firstDeveloper.html - - - Repo Add-on 1 - Second Developer - http://localhost:4444/repo/1/secondDeveloper.html - - - Repo Add-on 1 - Description<br>Second line - <p>Repo Add-on 1 - Full Description &amp; some extra</p> - Repo Add-on 1 - EULA - Repo Add-on 1 - Developer Comments - http://localhost/repo/1/icon.png - Public - 1 - http://localhost/repo/1/learnmore.html - http://localhost/repo/1/homepage.html - http://localhost/repo/1/support.html - - http://localhost/repo/1/contribution.html - $11.11 - http://localhost/repo/1/meetDevelopers.html - - http://localhost/repo/1/review.html - 2221 - 3331 - 4441 - 1970-01-01T00:00:09Z - http://localhost:4444/repo/1/install.xpi - - - - Repo Add-on 2 - Theme - test_AddonRepository_2@tests.mozilla.org - 2.2 - - - Repo Add-on 2 - Creator - http://localhost:4444/repo/2/creator.html - - - Repo Add-on 2 - First Developer - http://localhost:4444/repo/2/firstDeveloper.html - - - Repo Add-on 2 - Second Developer - http://localhost:4444/repo/2/secondDeveloper.html - - - Repo Add-on 2 - Description - Repo Add-on 2 - Full Description - Repo Add-on 2 - EULA - Repo Add-on 2 - Developer Comments - http://localhost/repo/2/icon.png - Unknown - - - http://localhost:4444/repo/2/firstFull.png - http://localhost:4444/repo/2/firstThumbnail.png - Repo Add-on 2 - First Caption - - - http://localhost:4444/repo/2/secondFull.png - http://localhost:4444/repo/2/secondThumbnail.png - Repo Add-on 2 - Second Caption - - - 2 - http://localhost/repo/2/learnmore.html - http://localhost/repo/2/homepage.html - http://localhost/repo/2/support.html - - http://localhost/repo/2/contribution.html - http://localhost/repo/2/meetDevelopers.html - - http://localhost/repo/2/review.html - 2222 - 3332 - 4442 - 1970-01-01T00:00:09Z - http://localhost:4444/repo/2/install.xpi - - - - Repo Add-on 3 - Theme - test_AddonRepository_3@tests.mozilla.org - 2.3 - http://localhost/repo/3/icon.png - - - http://localhost:4444/repo/3/firstFull.png - http://localhost:4444/repo/3/firstThumbnail.png - Repo Add-on 3 - First Caption - - - http://localhost:4444/repo/3/secondFull.png - http://localhost:4444/repo/3/secondThumbnail.png - Repo Add-on 3 - Second Caption - - - - - - test_AddonRepository_1@tests.mozilla.org - PASS - - - - 0.1 - 0.2 - - - XPCShell - 666 - 3.0 - 4.0 - xpcshell@tests.mozilla.org - - - - - - 0.2 - 0.3 - - - XPCShell - 666 - 5.0 - 6.0 - xpcshell@tests.mozilla.org - - - - - - 9 - 10 - - - XPCShell - 666 - 10.0 - 11.0 - xpcshell@tests.mozilla.org - - - - - - 0.2 - 0.3 - - - Unknown App - 123 - 1.0 - 999.0 - unknown-app@tests.mozilla.org - - - - - - - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache_compat.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache_compat.json new file mode 100644 index 000000000000..7457484ce146 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_cache_compat.json @@ -0,0 +1,52 @@ +{ + "page_size": 25, + "page_count": 1, + "count": 4, + "next": null, + "previous": null, + "results": [ + { + "name": "PASS", + "addon_guid": "test_AddonRepository_1@tests.mozilla.org", + "version_ranges": [ + { + "addon_min_version": "0.1", + "addon_max_version": "0.2", + "applications": [ + { + "name": "XPCShell", + "guid": "xpcshell@tests.mozilla.org", + "min_version": "3.0", + "max_version": "4.0" + } + ] + }, + { + "addon_min_version": "0.2", + "addon_max_version": "0.3", + "applications": [ + { + "name": "XPCShell", + "guid": "xpcshell@tests.mozilla.org", + "min_version": "5.0", + "max_version": "6.0" + } + ] + }, + { + "addon_min_version": "0.2", + "addon_max_version": "0.3", + "applications": [ + { + "name": "Unknown App", + "guid": "unknown-app@tests.mozilla.org", + "min_version": "1.0", + "max_version": "999.0" + } + ] + } + ] + } + ] +} + diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_empty.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_empty.json new file mode 100644 index 000000000000..64fac5dc8bf9 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_empty.json @@ -0,0 +1,7 @@ +{ + "page_size": 25, + "count": 0, + "next": null, + "previous": null, + "results": [] +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_empty.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_empty.xml deleted file mode 100644 index 4cd5c144331b..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_empty.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_fail.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_fail.json new file mode 100644 index 000000000000..d29d525a81f5 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_fail.json @@ -0,0 +1 @@ +this should yield a json parse error diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_failed.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_failed.xml deleted file mode 100644 index d02fa0249588..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_failed.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - PASS - Extension - test1@tests.mozilla.org - 1.1 - Test Creator 1 - Public - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test1.xpi -
- - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_getAddonsByIDs.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_getAddonsByIDs.json new file mode 100644 index 000000000000..733ea4883b0c --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_getAddonsByIDs.json @@ -0,0 +1,101 @@ +{ + "page_size": 25, + "page_count": 1, + "count": 4, + "next": null, + "previous": null, + "results": [ + { + "name": "PASS", + "type": "extension", + "guid": "test1@tests.mozilla.org", + "current_version": { + "version": "1.1", + "files": [ + { + "platform": "all", + "url": "http://localhost:%PORT%/addons/test_AddonRepository_2.xpi", + "size": 5555 + } + ] + }, + "authors": [ + { + "name": "Test Creator 1", + "url": "http://localhost:%PORT%/creator1.html" + }, + { + "name": "Test Developer 1", + "url": "http://localhost:%PORT%/developer1.html" + } + ], + "summary": "Test Summary 1", + "description": "Test Description 1", + "icons": { + "32": "http://localhost:%PORT%/icon1.png" + }, + "previews": [ + { + "caption": "Caption 1 - 1", + "image_size": [400, 300], + "image_url": "http://localhost:%PORT%/full1-1.png", + "thumbnail_size": [200, 150], + "thumbnail_url": "http://localhost:%PORT%/thumbnail1-1.png" + }, + { + "caption": "Caption 2 - 1", + "image_url": "http://localhost:%PORT%/full2-1.png", + "thumbnail_url": "http://localhost:%PORT%/thumbnail2-1.png" + } + ], + "ratings": { + "count": 1111, + "average": 4 + }, + "ratings_url": "http://localhost:%PORT%/review1.html", + "support_url": "http://localhost:%PORT%/support1.html", + "contributions_url": "http://localhost:%PORT%/contribution1.html", + "weekly_downloads": 3333, + "last_updated": "2010-02-01T14:04:05Z" + }, + { + "name": "FAIL", + "type": "extension", + "guid": "notRequested@tests.mozilla.org", + "current_version": { + "version": "1.3", + "files": [ + { + "platform": "all", + "url": "http://localhost:%PORT%/test3.xpi" + } + ] + }, + "authors": [ + { + "name": "Test Creator 3" + } + ], + "summary": "Add-on with a guid that wasn't requested should be ignored." + }, + { + "name": "PASS", + "type": "theme", + "guid": "test_AddonRepository_1@tests.mozilla.org", + "current_version": { + "version": "1.4", + "files": [ + { + "platform": "UNKNOWN1", + "url": "http://localhost:%PORT%/test4.xpi" + }, + { + "platform": "UNKNOWN2", + "url": "http://localhost:%PORT%/test4.xpi" + } + ] + } + } + ] +} + diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_getAddonsByIDs.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_getAddonsByIDs.xml deleted file mode 100644 index 8a616796955c..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_AddonRepository_getAddonsByIDs.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - - - PASS - Extension - test1@tests.mozilla.org - 1.1 - - - Test Creator 1 - http://localhost:%PORT%/creator1.html - - - Test Developer 1 - http://localhost:%PORT%/developer1.html - - - Test Summary 1 - Test Description 1 - Test EULA 1 - Test Developer Comments 1 - http://localhost:%PORT%/icon1.png - Preliminarily Reviewed - - - xpcshell@tests.mozilla.org - 1 - 1 - - - - - - http://localhost:%PORT%/full1-1.png - - - http://localhost:%PORT%/thumbnail1-1.png - - Caption 1 - 1 - - - http://localhost:%PORT%/full2-1.png - http://localhost:%PORT%/thumbnail2-1.png - Caption 2 - 1 - - - 4 - http://localhost:%PORT%/learnmore1.html - http://localhost:%PORT%/support1.html - - http://localhost:%PORT%/contribution1.html - $11.11 - http://localhost:%PORT%/meetDevelopers1.html - - http://localhost:%PORT%/review1.html - 2222 - 3333 - 4444 - 2010-02-01T14:04:05Z - http://localhost:%PORT%/addons/test_AddonRepository_2.xpi - - - - test1@tests.mozilla.org - PASS - - - - 0.1 - 0.2 - - - XPCShell - 666 - 3.0 - 4.0 - xpcshell@tests.mozilla.org - - - - - - 0.2 - 0.3 - - - XPCShell - 666 - 5.0 - 6.0 - xpcshell@tests.mozilla.org - - - - - - 9 - 10 - - - XPCShell - 666 - 10.0 - 11.0 - xpcshell@tests.mozilla.org - - - - - - 0.2 - 0.3 - - - Unknown App - 123 - 1.0 - 999.0 - unknown-app@tests.mozilla.org - - - - - - - - - FAIL - Extension - test1@tests.mozilla.org - 1.2 - Test Creator 2 - Public - Add-on with a guid that matches a previously successful result should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test2.xpi - - - - - FAIL - Extension - notRequested@tests.mozilla.org - 1.3 - Test Creator 3 - Public - Add-on with a guid that wasn't requested should be ignored. - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test3.xpi - - - - - PASS - Theme - test_AddonRepository_1@tests.mozilla.org - 1.4 - Unknown - - - unknown@tests.mozilla.org - 1 - 1 - - - http://localhost:%PORT%/test4.xpi - http://localhost:%PORT%/test4.xpi - - - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_compatoverrides.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_compatoverrides.xml deleted file mode 100644 index c0d67d033478..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_compatoverrides.xml +++ /dev/null @@ -1,228 +0,0 @@ - - - - Test addon 2 - Extension - addon2@tests.mozilla.org - 1.0 - - - - Test addon 3 - Extension - addon3@tests.mozilla.org - 1.0 - - - Test addon 3 - addon3@tests.mozilla.org - - - 0.9 - 1.0 - - - XPCShell - xpcshell@tests.mozilla.org - 1 - 2 - - - - - - - - Test addon 4 - Extension - addon4@tests.mozilla.org - 1.0 - - - Test addon 4 - addon4@tests.mozilla.org - - - 0.9 - 1.0 - - - XPCShell - xpcshell@tests.mozilla.org - 1 - 2 - - - - - - - - Test addon 5 - Extension - addon5@tests.mozilla.org - 1.0 - - - Test addon 5 - addon5@tests.mozilla.org - - - 0.9 - 1.0 - - - Unknown App - unknown-app@tests.mozilla.org - 1 - 2 - - - - - - - - Test addon 6 - Extension - addon6@tests.mozilla.org - 1.0 - - - Test addon 6 - addon6@tests.mozilla.org - - - 0.5 - 0.9 - - - XPCShell - xpcshell@tests.mozilla.org - 1 - 2 - - - - - - - - Test addon 7 - Extension - addon7@tests.mozilla.org - 1.0 - - - Test addon 7 - addon7@tests.mozilla.org - - - 0.5 - 1.0 - - - XPCShell - xpcshell@tests.mozilla.org - 0.1 - 0.9 - - - - - - - - Test addon 8 - Extension - addon8@tests.mozilla.org - 1.0 - - - Test addon 8 - addon8@tests.mozilla.org - - - 6 - 6.2 - - - XPCShell - xpcshell@tests.mozilla.org - 0.9 - 9 - - - - - 0.5 - 1.0 - - - XPCShell - xpcshell@tests.mozilla.org - 0.1 - 9 - - - Unknown app - unknown-app@tests.mozilla.org - 0.1 - 9 - - - - - 0.1 - 0.2 - - - XPCShell - xpcshell@tests.mozilla.org - 0.1 - 0.9 - - - - - - - - Test addon 9 - addon9@tests.mozilla.org - - - 0.5 - 1.0 - - - XPCShell - xpcshell@tests.mozilla.org - 1 - 2 - - - - - - - - Test addon 10 - addon10@tests.mozilla.org - - - 0.5 - 1.0 - - - XPCShell - xpcshell@tests.mozilla.org - 1 - 2 - - - - - - - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_install.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_install.xml deleted file mode 100644 index 33f14a2fdcff..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_install.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - Real Test 2 - Extension - addon2@tests.mozilla.org - 1.0 - - - Test Creator - http://example.com/creator.html - - - Public - Repository summary - Repository description - - - Firefox - {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 0 - * - - - SeaMonkey - {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} - 0 - * - - - ALL - http://example.com/browser/toolkit/mozapps/extensions/test/browser/addons/browser_install1_2.xpi - - - - addon6@tests.mozilla.org - Addon Test 6 - - - 1.0 - 1.0 - - - XPCShell - 1.0 - 1.0 - xpcshell@tests.mozilla.org - - - - - - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_install_addons.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_install_addons.json new file mode 100644 index 000000000000..cb1f2f4faeb6 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_install_addons.json @@ -0,0 +1,31 @@ +{ + "page_size": 25, + "page_count": 1, + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "name": "Real Test 2", + "type": "extension", + "guid": "addon2@tests.mozilla.org", + "current_version": { + "version": "1.0", + "files": [ + { + "size": 2, + "url": "http://example.com/browser/toolkit/mozapps/extensions/test/browser/addons/browser_install1_2.xpi" + } + ] + }, + "authors": [ + { + "name": "Test Creator", + "url": "http://example.com/creator.html" + } + ], + "summary": "Repository summary", + "description": "Repository description" + } + ] +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_install_compat.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_install_compat.json new file mode 100644 index 000000000000..a06819764810 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_install_compat.json @@ -0,0 +1,27 @@ +{ + "page_size": 25, + "page_count": 1, + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "addon_guid": "addon6@tests.mozilla.org", + "name": "Addon Test 6", + "version_ranges": [ + { + "addon_min_version": "1.0", + "addon_max_version": "1.0", + "applications": [ + { + "name": "XPCShell", + "guid": "xpcshell@tests.mozilla.org", + "min_version": "1.0", + "max_version": "1.0" + } + ] + } + ] + } + ] +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_sourceURI.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_sourceURI.xml deleted file mode 100644 index 949288e3f176..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_sourceURI.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - Test - Extension - addon@tests.mozilla.org - 1 - - - xpcshell@tests.mozilla.org - 1 - 1 - - - http://www.example.com/testaddon.xpi - - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_update.xml b/toolkit/mozapps/extensions/test/xpcshell/data/test_update.xml deleted file mode 100644 index 62928815b739..000000000000 --- a/toolkit/mozapps/extensions/test/xpcshell/data/test_update.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - Test Addon 9 - Extension - addon9@tests.mozilla.org - - - addon9@tests.mozilla.org - Test Addon 9 - - - 4 - 4 - - - XPCShell - 1 - 1 - xpcshell@tests.mozilla.org - - - - - - diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_update_addons.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_update_addons.json new file mode 100644 index 000000000000..3bcbc022e0a0 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_update_addons.json @@ -0,0 +1,14 @@ +{ + "page_size": 25, + "page_count": 1, + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "name": "Ttest Addon 9", + "type": "extension", + "guid": "addon9@tests.mozilla.org" + } + ] +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/test_update_compat.json b/toolkit/mozapps/extensions/test/xpcshell/data/test_update_compat.json new file mode 100644 index 000000000000..9721d3466a29 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/data/test_update_compat.json @@ -0,0 +1,28 @@ +{ + "page_size": 25, + "page_count": 1, + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "addon_guid": "addon9@tests.mozilla.org", + "name": "Test Addon 9", + "version_ranges": [ + { + "addon_min_version": "4", + "addon_max_version": "4", + "applications": [ + { + "name": "XPCShell", + "id": "XPCShell", + "guid": "xpcshell@tests.mozilla.org", + "min_version": "1", + "max_version": "1" + } + ] + } + ] + } + ] +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js index 0d4520649c9d..300267c54e43 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js +++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js @@ -18,7 +18,7 @@ const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility"; const PREF_EM_MIN_COMPAT_APP_VERSION = "extensions.minCompatibleAppVersion"; const PREF_EM_MIN_COMPAT_PLATFORM_VERSION = "extensions.minCompatiblePlatformVersion"; const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url"; -const PREF_GETADDONS_BYIDS_PERFORMANCE = "extensions.getAddons.getWithPerformance.url"; +const PREF_COMPAT_OVERRIDES = "extensions.getAddons.compatOverides.url"; const PREF_XPI_SIGNATURES_REQUIRED = "xpinstall.signatures.required"; const PREF_SYSTEM_ADDON_SET = "extensions.systemAddonSet"; const PREF_SYSTEM_ADDON_UPDATE_URL = "extensions.systemAddon.update.url"; diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js index f948762a9505..a86f5633c52f 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js @@ -27,14 +27,12 @@ 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", + "description", "fullDescription", + "iconURL", "icons", "screenshots", + "supportURL", "contributionURL", "averageRating", "reviewCount", "reviewURL", - "totalDownloads", "weeklyDownloads", "dailyUsers", - "sourceURI", "repositoryStatus", "size", "updateDate", - "purchaseURL", "purchaseAmount", "purchaseDisplayAmount", - "compatibilityOverrides"]; + "weeklyDownloads", "dailyUsers", + "sourceURI", "size", "updateDate"]; // Results of getAddonsByIDs var GET_RESULTS = [{ @@ -51,8 +49,6 @@ var GET_RESULTS = [{ }], 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: [{ @@ -68,64 +64,38 @@ var GET_RESULTS = [{ 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", + contributionURL: BASE_URL + "/contribution1.html", 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: {} }]; // Values for testing AddonRepository.getAddonsByIDs() var GET_TEST = { preference: PREF_GETADDONS_BYIDS, - preferenceValue: BASE_URL + "/%OS%/%VERSION%/%API_VERSION%/" + - "%API_VERSION%/%IDS%", + preferenceValue: BASE_URL + "/%OS%/%VERSION%/%IDS%", failedIDs: ["test1@tests.mozilla.org"], - failedURL: "/XPCShell/1/1.5/1.5/test1%40tests.mozilla.org", + failedURL: "/XPCShell/1/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," + + successfulURL: "/XPCShell/1/test1%40tests.mozilla.org%2C" + + "%7B00000000-1111-2222-3333-444444444444%7D%2C" + "test_AddonRepository_1%40tests.mozilla.org" }; // Test that actual results and expected results are equal -function check_results(aActualAddons, aExpectedAddons, aAddonCount, aInstallNull) { - Assert.ok(!AddonRepository.isSearching); - - Assert.equal(aActualAddons.length, aAddonCount); +function check_results(aActualAddons, aExpectedAddons) { do_check_addons(aActualAddons, aExpectedAddons, ADDON_PROPERTIES); // Additional tests @@ -136,56 +106,9 @@ function check_results(aActualAddons, aExpectedAddons, aAddonCount, aInstallNull if (aActualAddon.name != "PASS") do_throw(aActualAddon.id + " - invalid add-on name " + aActualAddon.name); - Assert.equal(aActualAddon.install == null, !!aInstallNull || !aActualAddon.sourceURI); - - // Check that sourceURI property consistent within actual addon - if (aActualAddon.install) - Assert.equal(aActualAddon.install.sourceURI.spec, aActualAddon.sourceURI.spec); }); } -// Complete a search, also testing cancelSearch() and isSearching -function complete_search(aSearch, aSearchCallback) { - var failCallback = { - searchSucceeded(addons, length, total) { - do_throw("failCallback.searchSucceeded should not be called"); - end_test(); - }, - - searchFailed() { - do_throw("failCallback.searchFailed should not be called"); - end_test(); - } - }; - - var callbackCalled = false; - var testCallback = { - searchSucceeded(addons, length, total) { - do_throw("testCallback.searchSucceeded should not be called"); - end_test(); - }, - - searchFailed() { - callbackCalled = true; - } - }; - - // Should fail because cancelled it immediately - aSearch(failCallback); - Assert.ok(AddonRepository.isSearching); - AddonRepository.cancelSearch(); - Assert.ok(!AddonRepository.isSearching); - - aSearch(aSearchCallback); - Assert.ok(AddonRepository.isSearching); - - // searchFailed should be called immediately because already searching - aSearch(testCallback); - Assert.ok(callbackCalled); - Assert.ok(AddonRepository.isSearching); -} - - function run_test() { // Setup for test do_test_pending(); @@ -205,12 +128,12 @@ function run_test() { // Register files used to test search failure mapUrlToFile(GET_TEST.failedURL, - do_get_file("data/test_AddonRepository_failed.xml"), + do_get_file("data/test_AddonRepository_fail.json"), gServer); // Register files used to test search success mapUrlToFile(GET_TEST.successfulURL, - do_get_file("data/test_AddonRepository_getAddonsByIDs.xml"), + do_get_file("data/test_AddonRepository_getAddonsByIDs.json"), gServer); // Create an active AddonInstall so can check that it isn't returned in the results @@ -312,39 +235,21 @@ function run_test_1() { // Tests failure of AddonRepository.getAddonsByIDs() function run_test_getAddonsByID_fails() { Services.prefs.setCharPref(GET_TEST.preference, GET_TEST.preferenceValue); - var callback = { - searchSucceeded(aAddonsList, aAddonCount, aTotalResults) { - do_throw("searchAddons should not have succeeded"); - end_test(); - }, - - searchFailed() { - Assert.ok(!AddonRepository.isSearching); - run_test_getAddonsByID_succeeds(); - } - }; - - complete_search(function complete_search_fail_callback(aCallback) { - AddonRepository.getAddonsByIDs(GET_TEST.failedIDs, aCallback); - }, callback); + AddonRepository.getAddonsByIDs(GET_TEST.failedIDs).then(result => { + do_throw("getAddonsByIDs should not have succeeded"); + end_test(); + }).catch(err => { + run_test_getAddonsByID_succeeds(); + }); } // Tests success of AddonRepository.getAddonsByIDs() function run_test_getAddonsByID_succeeds() { - var callback = { - searchSucceeded(aAddonsList, aAddonCount, aTotalResults) { - Assert.equal(aTotalResults, -1); - check_results(aAddonsList, GET_RESULTS, aAddonCount, true); - end_test(); - }, - - searchFailed() { - do_throw("searchAddons should not have failed"); - end_test(); - } - }; - - complete_search(function complete_search_succeed_callback(aCallback) { - AddonRepository.getAddonsByIDs(GET_TEST.successfulIDs, aCallback); - }, callback); + AddonRepository.getAddonsByIDs(GET_TEST.successfulIDs).then(result => { + check_results(result, GET_RESULTS); + end_test(); + }).catch(err => { + do_throw(err); + end_test(); + }); } diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js index d62aef5ac665..bb5109beee4f 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js @@ -13,9 +13,10 @@ const BASE_URL = "http://localhost:" + PORT; const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled"; const PREF_GETADDONS_CACHE_TYPES = "extensions.getAddons.cache.types"; -const GETADDONS_RESULTS = BASE_URL + "/data/test_AddonRepository_cache.xml"; -const GETADDONS_EMPTY = BASE_URL + "/data/test_AddonRepository_empty.xml"; -const GETADDONS_FAILED = BASE_URL + "/data/test_AddonRepository_failed.xml"; +const GETADDONS_RESULTS = BASE_URL + "/data/test_AddonRepository_cache.json"; +const COMPAT_RESULTS = BASE_URL + "/data/test_AddonRepository_cache_compat.json"; +const EMPTY_RESULT = BASE_URL + "/data/test_AddonRepository_empty.json"; +const FAILED_RESULT = BASE_URL + "/data/test_AddonRepository_fail.json"; const FILE_DATABASE = "addons.json"; const ADDON_NAMES = ["test_AddonRepository_1", @@ -32,13 +33,11 @@ const PREF_ADDON1_CACHE_ENABLED = "extensions." + ADDON_IDS[1] + ".getAddons.cac const ADDON_PROPERTIES = ["id", "type", "name", "version", "creator", "developers", "translators", "contributors", "description", "fullDescription", - "developerComments", "eula", "iconURL", "icons", + "iconURL", "icons", "screenshots", "homepageURL", "supportURL", "optionsURL", "aboutURL", "contributionURL", - "contributionAmount", "averageRating", "reviewCount", - "reviewURL", "totalDownloads", "weeklyDownloads", - "dailyUsers", "sourceURI", "repositoryStatus", - "compatibilityOverrides"]; + "averageRating", "reviewCount", + "reviewURL", "weeklyDownloads", "sourceURI"]; // The size and updateDate properties are annoying to test for XPI add-ons. // However, since we only care about whether the repository value vs. the @@ -75,37 +74,16 @@ const REPOSITORY_ADDONS = [{ }], description: "Repo Add-on 1 - Description\nSecond line", fullDescription: "Repo Add-on 1 - Full Description & some extra", - developerComments: "Repo Add-on 1\nDeveloper Comments", - eula: "Repo Add-on 1 - EULA", iconURL: BASE_URL + "/repo/1/icon.png", icons: { "32": BASE_URL + "/repo/1/icon.png" }, homepageURL: BASE_URL + "/repo/1/homepage.html", supportURL: BASE_URL + "/repo/1/support.html", contributionURL: BASE_URL + "/repo/1/meetDevelopers.html", - contributionAmount: "$11.11", averageRating: 1, reviewCount: 1111, reviewURL: BASE_URL + "/repo/1/review.html", - totalDownloads: 2221, weeklyDownloads: 3331, - dailyUsers: 4441, - sourceURI: BASE_URL + "/repo/1/install.xpi", - repositoryStatus: 4, - 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 - }] + sourceURI: BASE_URL + "/repo/1/install.xpi" }, { id: ADDON_IDS[1], type: "theme", @@ -124,8 +102,6 @@ const REPOSITORY_ADDONS = [{ }], description: "Repo Add-on 2 - Description", fullDescription: "Repo Add-on 2 - Full Description", - developerComments: "Repo Add-on 2 - Developer Comments", - eula: "Repo Add-on 2 - EULA", iconURL: BASE_URL + "/repo/2/icon.png", icons: { "32": BASE_URL + "/repo/2/icon.png" }, screenshots: [{ @@ -140,15 +116,11 @@ const REPOSITORY_ADDONS = [{ homepageURL: BASE_URL + "/repo/2/homepage.html", supportURL: BASE_URL + "/repo/2/support.html", contributionURL: BASE_URL + "/repo/2/meetDevelopers.html", - contributionAmount: null, averageRating: 2, reviewCount: 1112, reviewURL: BASE_URL + "/repo/2/review.html", - totalDownloads: 2222, weeklyDownloads: 3332, - dailyUsers: 4442, sourceURI: BASE_URL + "/repo/2/install.xpi", - repositoryStatus: 9 }, { id: ADDON_IDS[2], type: "theme", @@ -229,7 +201,6 @@ const WITH_CACHE = [{ { name: "XPI Add-on 1 - Second Contributor" }], description: "XPI Add-on 1 - Description", fullDescription: "Repo Add-on 1 - Full Description & some extra", - developerComments: "Repo Add-on 1\nDeveloper Comments", eula: "Repo Add-on 1 - EULA", iconURL: BASE_URL + "/xpi/1/icon.png", icons: { "32": BASE_URL + "/xpi/1/icon.png" }, @@ -247,21 +218,6 @@ const WITH_CACHE = [{ dailyUsers: 4441, sourceURI: NetUtil.newURI(ADDON_FILES[0]).spec, repositoryStatus: 4, - 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: ADDON_IDS[1], type: "theme", @@ -280,7 +236,6 @@ const WITH_CACHE = [{ }], description: "Repo Add-on 2 - Description", fullDescription: "Repo Add-on 2 - Full Description", - developerComments: "Repo Add-on 2 - Developer Comments", eula: "Repo Add-on 2 - EULA", iconURL: BASE_URL + "/repo/2/icon.png", icons: { "32": BASE_URL + "/repo/2/icon.png" }, @@ -346,7 +301,6 @@ const WITH_EXTENSION_CACHE = [{ { name: "XPI Add-on 1 - Second Contributor" }], description: "XPI Add-on 1 - Description", fullDescription: "Repo Add-on 1 - Full Description & some extra", - developerComments: "Repo Add-on 1\nDeveloper Comments", eula: "Repo Add-on 1 - EULA", iconURL: BASE_URL + "/xpi/1/icon.png", icons: { "32": BASE_URL + "/xpi/1/icon.png" }, @@ -364,21 +318,6 @@ const WITH_EXTENSION_CACHE = [{ dailyUsers: 4441, sourceURI: NetUtil.newURI(ADDON_FILES[0]).spec, repositoryStatus: 4, - 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: ADDON_IDS[1], type: "theme", @@ -523,25 +462,28 @@ add_task(async function run_test_2() { add_task(async function run_test_3() { Assert.ok(gDBFile.exists()); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, GETADDONS_FAILED); + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, FAILED_RESULT); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, FAILED_RESULT); - await AddonRepository.repopulateCache(); + await AddonRepository.backgroundUpdateCheck(); await check_initialized_cache([false, false, false]); }); // Tests repopulateCache when search returns no results add_task(async function run_test_4() { - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, GETADDONS_EMPTY); + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, EMPTY_RESULT); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, FAILED_RESULT); - await AddonRepository.repopulateCache(); + await AddonRepository.backgroundUpdateCheck(); await check_initialized_cache([false, false, false]); }); // Tests repopulateCache when search returns results add_task(async function run_test_5() { Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, GETADDONS_RESULTS); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, COMPAT_RESULTS); - await AddonRepository.repopulateCache(); + await AddonRepository.backgroundUpdateCheck(); await check_initialized_cache([true, true, true]); }); @@ -549,7 +491,7 @@ add_task(async function run_test_5() { add_task(async function run_test_5_1() { Services.prefs.setBoolPref(PREF_ADDON0_CACHE_ENABLED, false); - await AddonRepository.repopulateCache(); + await AddonRepository.backgroundUpdateCheck(); // Reset pref for next test Services.prefs.setBoolPref(PREF_ADDON0_CACHE_ENABLED, true); @@ -562,7 +504,7 @@ add_task(async function run_test_6() { Assert.ok(gDBFile.exists()); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, false); - await AddonRepository.repopulateCache(); + await AddonRepository.backgroundUpdateCheck(); // Database should have been deleted Assert.ok(!gDBFile.exists()); @@ -574,19 +516,17 @@ add_task(async function run_test_6() { // Tests cacheAddons when the search fails add_task(async function run_test_7() { Assert.ok(gDBFile.exists()); - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, GETADDONS_FAILED); + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, FAILED_RESULT); - await new Promise((resolve, reject) => - AddonRepository.cacheAddons(ADDON_IDS, resolve)); + await AddonRepository.cacheAddons(ADDON_IDS); await check_initialized_cache([false, false, false]); }); // Tests cacheAddons when the search returns no results add_task(async function run_test_8() { - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, GETADDONS_EMPTY); + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, EMPTY_RESULT); - await new Promise((resolve, reject) => - AddonRepository.cacheAddons(ADDON_IDS, resolve)); + await AddonRepository.cacheAddons(ADDON_IDS); await check_initialized_cache([false, false, false]); }); @@ -594,8 +534,7 @@ add_task(async function run_test_8() { add_task(async function run_test_9() { Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, GETADDONS_RESULTS); - await new Promise((resolve, reject) => - AddonRepository.cacheAddons([ADDON_IDS[0]], resolve)); + await AddonRepository.cacheAddons([ADDON_IDS[0]]); await check_initialized_cache([true, false, false]); }); @@ -603,8 +542,7 @@ add_task(async function run_test_9() { add_task(async function run_test_9_1() { Services.prefs.setBoolPref(PREF_ADDON1_CACHE_ENABLED, false); - await new Promise((resolve, reject) => - AddonRepository.cacheAddons(ADDON_IDS, resolve)); + await AddonRepository.cacheAddons(ADDON_IDS); // Reset pref for next test Services.prefs.setBoolPref(PREF_ADDON1_CACHE_ENABLED, true); @@ -614,8 +552,7 @@ add_task(async function run_test_9_1() { // Tests cacheAddons for multiple add-ons, some already in the cache, add_task(async function run_test_10() { - await new Promise((resolve, reject) => - AddonRepository.cacheAddons(ADDON_IDS, resolve)); + await AddonRepository.cacheAddons(ADDON_IDS); await check_initialized_cache([true, true, true]); }); @@ -624,8 +561,7 @@ add_task(async function run_test_11() { Assert.ok(gDBFile.exists()); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, false); - await new Promise((resolve, reject) => - AddonRepository.cacheAddons(ADDON_IDS, resolve)); + await AddonRepository.cacheAddons(ADDON_IDS); Assert.ok(gDBFile.exists()); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); @@ -647,7 +583,7 @@ add_task(async function run_test_12() { // database, and that XPI add-ons still do not use any of repository properties add_task(async function run_test_13() { Assert.ok(gDBFile.exists()); - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE, GETADDONS_EMPTY); + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, EMPTY_RESULT); await AddonManagerInternal.backgroundUpdateCheck(); // Database should have been deleted @@ -673,7 +609,7 @@ add_task(async function run_test_14() { // Tests that the XPI add-ons correctly use the repository properties when // caching is enabled and the repository information is available add_task(async function run_test_15() { - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE, GETADDONS_RESULTS); + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, GETADDONS_RESULTS); await AddonManagerInternal.backgroundUpdateCheck(); let aAddons = await promiseAddonsByIDs(ADDON_IDS); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_paging.js b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_paging.js new file mode 100644 index 000000000000..337cabf420e8 --- /dev/null +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_paging.js @@ -0,0 +1,79 @@ + +// Test that AMO api results that are returned in muliple pages are +// properly handled. +add_task(async function test_paged_api() { + const MAX_ADDON = 3; + + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2"); + + let testserver = createHttpServer(); + const PORT = testserver.identity.primaryPort; + + const EMPTY_RESPONSE = { + next: null, + results: [], + }; + + function name(n) { return `Addon ${n}`; } + function id(n) { return `test${n}@tests.mozilla.org`; } + function summary(n) { return `Summary for addon ${n}`; } + function description(n) { return `Description for addon ${n}`; } + + testserver.registerPathHandler("/empty", (request, response) => { + response.setHeader("content-type", "application/json"); + response.write(JSON.stringify(EMPTY_RESPONSE)); + }); + + testserver.registerPrefixHandler("/addons/", (request, response) => { + let [page, ] = /\d+/.exec(request.path); + page = page ? parseInt(page, 10) : 0; + page = Math.min(page, MAX_ADDON); + + let result = { + next: (page == MAX_ADDON) ? null : `http://localhost:${PORT}/addons/${page + 1}`, + results: [ + { + name: name(page), + type: "extension", + guid: id(page), + summary: summary(page), + description: description(page), + }, + ], + }; + + response.setHeader("content-type", "application/json"); + response.write(JSON.stringify(result)); + }); + + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, `http://localhost:${PORT}/addons/0`); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, `http://localhost:${PORT}/empty`); + + await promiseStartupManager(); + + for (let i = 0; i <= MAX_ADDON; i++) { + await promiseInstallWebExtension({ + manifest: { + applications: {gecko: {id: id(i)}}, + }, + }); + } + + await AddonManagerInternal.backgroundUpdateCheck(); + + let ids = []; + for (let i = 0; i <= MAX_ADDON; i++) { + ids.push(id(i)); + } + let addons = await AddonRepository.getAddonsByIDs(ids); + + equal(addons.length, MAX_ADDON + 1); + for (let i = 0; i <= MAX_ADDON; i++) { + equal(addons[i].name, name(i)); + equal(addons[i].id, id(i)); + equal(addons[i].description, summary(i)); + equal(addons[i].fullDescription, description(i)); + } + + await promiseShutdownManager(); +}); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js b/toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js index d4461323f577..c656326a1236 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js @@ -14,15 +14,181 @@ gPort = gServer.identity.primaryPort; const PORT = gPort; const BASE_URL = "http://localhost:" + PORT; -const REQ_URL = "/data.xml"; -// register static file and mark it for interpolation -mapUrlToFile(REQ_URL, do_get_file("data/test_compatoverrides.xml"), gServer); +const GETADDONS_RESPONSE = { + next: null, + previous: null, + results: [], +}; +gServer.registerPathHandler("/addons.json", (request, response) => { + response.setHeader("content-type", "application/json"); + response.write(JSON.stringify(GETADDONS_RESPONSE)); +}); + +const COMPAT_RESPONSE = { + next: null, + previous: null, + results: [ + { + addon_guid: "addon3@tests.mozilla.org", + version_ranges: [ + { + addon_min_version: "0.9", + addon_max_version: "1.0", + applications: [ + { + name: "XPCShell", + guid: "xpcshell@tests.mozilla.org", + min_version: "1", + max_version: "2", + }, + ], + } + ] + }, + { + addon_guid: "addon4@tests.mozilla.org", + version_ranges: [ + { + addon_min_version: "0.9", + addon_max_version: "1.0", + applications: [ + { + name: "XPCShell", + guid: "xpcshell@tests.mozilla.org", + min_version: "1", + max_version: "2", + }, + ], + }, + ], + }, + { + addon_guid: "addon5@tests.mozilla.org", + version_ranges: [ + { + addon_min_version: "0.9", + addon_max_version: "1.0", + applications: [ + { + name: "Unknown App", + guid: "unknown-app@tests.mozilla.org", + min_version: "1", + max_version: "2", + }, + ], + }, + ], + }, + { + addon_guid: "addon6@tests.mozilla.org", + version_ranges: [ + { + addon_min_version: "0.5", + addon_max_version: "0.9", + applications: [ + { + name: "XPCShell", + guid: "xpcshell@tests.mozilla.org", + min_version: "1", + max_version: "2", + }, + ], + }, + ], + }, + { + addon_guid: "addon7@tests.mozilla.org", + version_ranges: [ + { + addon_min_version: "0.5", + addon_max_version: "1.0", + applications: [ + { + name: "XPCShell", + guid: "xpcshell@tests.mozilla.org", + min_version: "0.1", + max_version: "0.9", + }, + ], + }, + ], + }, + { + addon_guid: "addon8@tests.mozilla.org", + version_ranges: [ + { + addon_min_version: "6", + addon_max_version: "6.2", + applications: [ + { + name: "XPCShell", + guid: "xpcshell@tests.mozilla.org", + min_version: "0.9", + max_version: "9", + }, + ], + }, + { + addon_min_version: "0.5", + addon_max_version: "1.0", + applications: [ + { + name: "XPCShell", + guid: "xpcshell@tests.mozilla.org", + min_version: "0.1", + max_version: "9", + }, + { + name: "Unknown app", + guid: "unknown-app@tests.mozilla.org", + min_version: "0.1", + max_version: "9", + } + ], + }, + { + addon_min_version: "0.1", + addon_max_version: "0.2", + applications: [ + { + name: "XPCShell", + guid: "xpcshell@tests.mozilla.org", + min_version: "0.1", + max_version: "0.9", + }, + ], + }, + ], + }, + { + addon_guid: "addon9@tests.mozilla.org", + version_ranges: [ + { + addon_min_version: "0.5", + addon_max_version: "1.0", + applications: [ + { + name: "XPCShell", + guid: "xpcshell@tests.mozilla.org", + min_version: "1", + max_version: "2", + }, + ], + }, + ], + }, + ], +}; +gServer.registerPathHandler("/compat.json", (request, response) => { + response.setHeader("content-type", "application/json"); + response.write(JSON.stringify(COMPAT_RESPONSE)); +}); Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); -Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE, - BASE_URL + REQ_URL); +Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, `${BASE_URL}/addons.json`); +Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, `${BASE_URL}/compat.json`); // Not hosted, no overrides @@ -133,19 +299,6 @@ var addon9 = { }] }; -// Not hosted, override is of unsupported type (compatible) -var addon10 = { - id: "addon10@tests.mozilla.org", - version: "1.0", - name: "Test addon 10", - targetApplications: [{ - id: "xpcshell@tests.mozilla.org", - minVersion: "1", - maxVersion: "1" - }] -}; - - const profileDir = gProfD.clone(); profileDir.append("extensions"); @@ -162,7 +315,6 @@ function run_test() { writeInstallRDFForExtension(addon7, profileDir); writeInstallRDFForExtension(addon8, profileDir); writeInstallRDFForExtension(addon9, profileDir); - writeInstallRDFForExtension(addon10, profileDir); startupManager(); @@ -182,9 +334,8 @@ function check_compat_status(aCallback) { "addon6@tests.mozilla.org", "addon7@tests.mozilla.org", "addon8@tests.mozilla.org", - "addon9@tests.mozilla.org", - "addon10@tests.mozilla.org"], - function([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]) { + "addon9@tests.mozilla.org"], + function([a1, a2, a3, a4, a5, a6, a7, a8, a9]) { Assert.notEqual(a1, null); Assert.equal(AddonRepository.getCompatibilityOverridesSync(a1.id), null); @@ -243,11 +394,6 @@ function check_compat_status(aCallback) { Assert.ok(!a9.isCompatible); Assert.ok(a9.appDisabled); - Assert.notEqual(a10, null); - Assert.equal(AddonRepository.getCompatibilityOverridesSync(a10.id), null); - Assert.ok(a10.isCompatible); - Assert.ok(!a10.appDisabled); - executeSoon(aCallback); }); } diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_install.js b/toolkit/mozapps/extensions/test/xpcshell/test_install.js index 97c1d239d77a..9dc4b01271cc 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_install.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_install.js @@ -983,7 +983,9 @@ function run_test_18_1() { Services.prefs.setBoolPref("extensions.getAddons.cache.enabled", true); Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, - "http://localhost:" + gPort + "/data/test_install.xml"); + "http://localhost:" + gPort + "/data/test_install_addons.json"); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, + "http://localhost:" + gPort + "/data/test_install_compat.json"); Services.prefs.setBoolPref("extensions.addon2@tests.mozilla.org.getAddons.cache.enabled", false); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_install_strictcompat.js b/toolkit/mozapps/extensions/test/xpcshell/test_install_strictcompat.js index 0ef1695ad9b3..de59178671b8 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_install_strictcompat.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_install_strictcompat.js @@ -962,7 +962,9 @@ function run_test_18_1() { Services.prefs.setBoolPref("extensions.getAddons.cache.enabled", true); Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, - "http://localhost:4444/data/test_install.xml"); + "http://localhost:4444/data/test_install_addons.json"); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, + "http://localhost:4444/data/test_install_compat.json"); Services.prefs.setBoolPref("extensions.addon2@tests.mozilla.org.getAddons.cache.enabled", false); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_sourceURI.js b/toolkit/mozapps/extensions/test/xpcshell/test_sourceURI.js index 03c8a179ad35..c898a672762c 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_sourceURI.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_sourceURI.js @@ -37,9 +37,43 @@ function backgroundUpdate(aCallback) { function run_test() { do_test_pending(); - mapUrlToFile("/cache.xml", do_get_file("data/test_sourceURI.xml"), gServer); - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, BASE_URL + "/cache.xml"); - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE, BASE_URL + "/cache.xml"); + const GETADDONS_RESPONSE = { + page_size: 25, + next: null, + previous: null, + results: [ + { + name: "Test", + type: "extension", + guid: "addon@tests.mozilla.org", + current_version: { + version: "1", + files: [ + { + platform: "all", + url: "http://www.example.com/testaddon.xpi" + }, + ], + }, + } + ], + }; + gServer.registerPathHandler("/addons.json", (request, response) => { + response.setHeader("content-type", "application/json"); + response.write(JSON.stringify(GETADDONS_RESPONSE)); + }); + + const COMPAT_RESPONSE = { + next: null, + results: [], + }; + gServer.registerPathHandler("/compat.json", (request, response) => { + response.setHeader("content-type", "application/json"); + response.write(JSON.stringify(COMPAT_RESPONSE)); + }); + + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, `${BASE_URL}/addons.json`); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, `${BASE_URL}/compat.json`); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_repository.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_repository.js index 597bdd1c0ae4..d86a4e3ddb1d 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_repository.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_repository.js @@ -17,14 +17,11 @@ registerDirectory("XREAppFeat", distroDir); createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "0"); -function getCachedAddon(id) { - return new Promise(resolve => AddonRepository.getCachedAddonByID(id, resolve)); -} - // Test with a missing features directory add_task(async function test_app_addons() { Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, `http://localhost:${gServer.identity.primaryPort}/get?%IDS%`); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, `http://localhost:${gServer.identity.primaryPort}/get?%IDS%`); gServer.registerPathHandler("/get", (request, response) => { do_throw("Unexpected request to server."); @@ -34,19 +31,17 @@ add_task(async function test_app_addons() { startupManager(); - await new Promise((resolve) => { - AddonRepository.cacheAddons(["system1@tests.mozilla.org", - "system2@tests.mozilla.org", - "system3@tests.mozilla.org"], resolve); - }); + await AddonRepository.cacheAddons(["system1@tests.mozilla.org", + "system2@tests.mozilla.org", + "system3@tests.mozilla.org"]); - let cached = await getCachedAddon("system1@tests.mozilla.org"); + let cached = await AddonRepository.getCachedAddonByID("system1@tests.mozilla.org"); Assert.equal(cached, null); - cached = await getCachedAddon("system2@tests.mozilla.org"); + cached = await AddonRepository.getCachedAddonByID("system2@tests.mozilla.org"); Assert.equal(cached, null); - cached = await getCachedAddon("system3@tests.mozilla.org"); + cached = await AddonRepository.getCachedAddonByID("system3@tests.mozilla.org"); Assert.equal(cached, null); await promiseShutdownManager(); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update.js b/toolkit/mozapps/extensions/test/xpcshell/test_update.js index f3a600e5dec8..1c7c921dabef 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update.js @@ -25,7 +25,8 @@ var testserver = createHttpServer(); gPort = testserver.identity.primaryPort; mapFile("/data/test_update.rdf", testserver); mapFile("/data/test_update.json", testserver); -mapFile("/data/test_update.xml", testserver); +mapFile("/data/test_update_addons.json", testserver); +mapFile("/data/test_update_compat.json", testserver); testserver.registerDirectory("/addons/", do_get_file("addons")); const profileDir = gProfD.clone(); @@ -1038,9 +1039,9 @@ for (let test of testParams) { }); Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, - "http://localhost:" + gPort + "/data/test_update.xml"); - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE, - "http://localhost:" + gPort + "/data/test_update.xml"); + `http://localhost:${gPort}/data/test_update_addons.json`); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, + `http://localhost:${gPort}/data/test_update_compat.json`); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); AddonManagerInternal.backgroundUpdateCheck(); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_ignorecompat.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_ignorecompat.js index d3b108afafd8..4c38cd4fbc53 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update_ignorecompat.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_ignorecompat.js @@ -15,7 +15,8 @@ var testserver = createHttpServer(); gPort = testserver.identity.primaryPort; mapFile("/data/test_update.rdf", testserver); mapFile("/data/test_update.json", testserver); -mapFile("/data/test_update.xml", testserver); +mapFile("/data/test_update_addons.json", testserver); +mapFile("/data/test_update_compat.json", testserver); testserver.registerDirectory("/addons/", do_get_file("addons")); const profileDir = gProfD.clone(); @@ -62,8 +63,10 @@ for (let test of testParams) { } }); - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE, - "http://localhost:" + gPort + "/data/" + updateFile); + Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, + `http://localhost:${gPort}/data/test_update_addons.json`); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, + `http://localhost:${gPort}/data/test_update_compat.json`); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); AddonManagerInternal.backgroundUpdateCheck(); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_strictcompat.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_strictcompat.js index 28b0574a26d3..87be0fe45de8 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update_strictcompat.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_strictcompat.js @@ -25,7 +25,8 @@ var testserver = createHttpServer(); gPort = testserver.identity.primaryPort; mapFile("/data/test_update.rdf", testserver); mapFile("/data/test_update.json", testserver); -mapFile("/data/test_update.xml", testserver); +mapFile("/data/test_update_addons.json", testserver); +mapFile("/data/test_update_compat.json", testserver); testserver.registerDirectory("/addons/", do_get_file("addons")); const profileDir = gProfD.clone(); @@ -977,9 +978,9 @@ for (let test of testParams) { }); Services.prefs.setCharPref(PREF_GETADDONS_BYIDS, - "http://localhost:" + gPort + "/data/test_update.xml"); - Services.prefs.setCharPref(PREF_GETADDONS_BYIDS_PERFORMANCE, - "http://localhost:" + gPort + "/data/test_update.xml"); + `http://localhost:${gPort}/data/test_update_addons.json`); + Services.prefs.setCharPref(PREF_COMPAT_OVERRIDES, + `http://localhost:${gPort}/data/test_update_compat.json`); Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true); AddonManagerInternal.backgroundUpdateCheck(); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_theme.js b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_theme.js index d0e70fff08b1..727cf13c2319 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_theme.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_theme.js @@ -60,10 +60,10 @@ add_task(async function setup_to_default_browserish_state() { name: "Bling", description: "SO MUCH BLING!", author: "Pixel Pusher", - homepageURL: "http://mochi.test:8888/data/index.html", - headerURL: "http://mochi.test:8888/data/header.png", - previewURL: "http://mochi.test:8888/data/preview.png", - iconURL: "http://mochi.test:8888/data/icon.png", + homepageURL: "http://localhost:8888/data/index.html", + headerURL: "http://localhost:8888/data/header.png", + previewURL: "http://localhost:8888/data/preview.png", + iconURL: "http://localhost:8888/data/icon.png", textcolor: Math.random().toString(), accentcolor: Math.random().toString() }; diff --git a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini index 7facec87c411..3dde6fbc22dc 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-shared.ini @@ -11,9 +11,9 @@ skip-if = os == "android" || os == "win" tags = webextensions [test_AddonRepository_cache.js] # Bug 676992: test consistently hangs on Android -# Bug 1026805: frequent hangs on OSX 10.8 -skip-if = os == "android" || os == "mac" +skip-if = os == "android" run-sequentially = Uses hardcoded ports in xpi files. +[test_AddonRepository_paging.js] [test_LightweightThemeManager.js] [test_backgroundupdate.js] [test_bad_json.js] @@ -284,8 +284,7 @@ tags = webextensions # Bug 676992: test consistently hangs on Android skip-if = os == "android" [test_update_ignorecompat.js] -# Bug 676992: test consistently hangs on Android -skip-if = os == "android" +skip-if = true # Bug 676922 Bug 1437697 [test_updatecheck.js] # Bug 676992: test consistently hangs on Android skip-if = os == "android"