mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 693906 - Parse and use new compatibility ranges in AMO metadata ping. r=dtownsend
This commit is contained in:
parent
de766e6f69
commit
993f3e5da9
@ -50,8 +50,11 @@ const PREF_EM_LAST_PLATFORM_VERSION = "extensions.lastPlatformVersion";
|
||||
const PREF_EM_AUTOUPDATE_DEFAULT = "extensions.update.autoUpdateDefault";
|
||||
const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility";
|
||||
|
||||
// Note: This has to be kept in sync with the same constant in AddonRepository.jsm
|
||||
const STRICT_COMPATIBILITY_DEFAULT = true;
|
||||
|
||||
const TOOLKIT_ID = "toolkit@mozilla.org";
|
||||
|
||||
const VALID_TYPES_REGEXP = /^[\w\-]+$/;
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
@ -235,6 +238,67 @@ AddonScreenshot.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This represents a compatibility override for an addon.
|
||||
*
|
||||
* @param aType
|
||||
* Overrride type - "compatible" or "incompatible"
|
||||
* @param aMinVersion
|
||||
* Minimum version of the addon to match
|
||||
* @param aMaxVersion
|
||||
* Maximum version of the addon to match
|
||||
* @param aAppID
|
||||
* Application ID used to match appMinVersion and appMaxVersion
|
||||
* @param aAppMinVersion
|
||||
* Minimum version of the application to match
|
||||
* @param aAppMaxVersion
|
||||
* Maximum version of the application to match
|
||||
*/
|
||||
function AddonCompatibilityOverride(aType, aMinVersion, aMaxVersion, aAppID,
|
||||
aAppMinVersion, aAppMaxVersion) {
|
||||
this.type = aType;
|
||||
this.minVersion = aMinVersion;
|
||||
this.maxVersion = aMaxVersion;
|
||||
this.appID = aAppID;
|
||||
this.appMinVersion = aAppMinVersion;
|
||||
this.appMaxVersion = aAppMaxVersion;
|
||||
}
|
||||
|
||||
AddonCompatibilityOverride.prototype = {
|
||||
/**
|
||||
* Type of override - "incompatible" or "compatible".
|
||||
* Only "incompatible" is supported for now.
|
||||
*/
|
||||
type: null,
|
||||
|
||||
/**
|
||||
* Min version of the addon to match.
|
||||
*/
|
||||
minVersion: null,
|
||||
|
||||
/**
|
||||
* Max version of the addon to match.
|
||||
*/
|
||||
maxVersion: null,
|
||||
|
||||
/**
|
||||
* Application ID to match.
|
||||
*/
|
||||
appID: null,
|
||||
|
||||
/**
|
||||
* Min version of the application to match.
|
||||
*/
|
||||
appMinVersion: null,
|
||||
|
||||
/**
|
||||
* Max version of the application to match.
|
||||
*/
|
||||
appMaxVersion: null
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A type of add-on, used by the UI to determine how to display different types
|
||||
* of add-ons.
|
||||
@ -555,8 +619,13 @@ var AddonManagerInternal = {
|
||||
let pendingUpdates = 1;
|
||||
|
||||
function notifyComplete() {
|
||||
if (--pendingUpdates == 0)
|
||||
Services.obs.notifyObservers(null, "addons-background-update-complete", null);
|
||||
if (--pendingUpdates == 0) {
|
||||
AddonManagerInternal.updateAddonRepositoryData(function BUC_updateAddonCallback() {
|
||||
Services.obs.notifyObservers(null,
|
||||
"addons-background-update-complete",
|
||||
null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let scope = {};
|
||||
@ -715,7 +784,31 @@ var AddonManagerInternal = {
|
||||
callProvider(provider, "updateAddonAppDisabledStates");
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Notifies all providers that the repository has updated its data for
|
||||
* installed add-ons.
|
||||
*
|
||||
* @param aCallback
|
||||
* Function to call when operation is complete.
|
||||
*/
|
||||
updateAddonRepositoryData: function AMI_updateAddonRepositoryData(aCallback) {
|
||||
if (!aCallback)
|
||||
throw Components.Exception("Must specify aCallback",
|
||||
Cr.NS_ERROR_INVALID_ARG);
|
||||
|
||||
new AsyncObjectCaller(this.providers, "updateAddonRepositoryData", {
|
||||
nextObject: function(aCaller, aProvider) {
|
||||
callProvider(aProvider,
|
||||
"updateAddonRepositoryData",
|
||||
null,
|
||||
aCaller.callNext.bind(aCaller));
|
||||
},
|
||||
noMoreObjects: function(aCaller) {
|
||||
safeCall(aCallback);
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Asynchronously gets an AddonInstall for a URL.
|
||||
*
|
||||
@ -1225,6 +1318,8 @@ var AddonManagerPrivate = {
|
||||
|
||||
AddonScreenshot: AddonScreenshot,
|
||||
|
||||
AddonCompatibilityOverride: AddonCompatibilityOverride,
|
||||
|
||||
AddonType: AddonType
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
# Contributor(s):
|
||||
# Dave Townsend <dtownsend@oxymoronical.com>
|
||||
# Ben Parr <bparr@bparr.com>
|
||||
# Blair McBride <bmcbride@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -74,6 +75,10 @@ XPCOMUtils.defineLazyGetter(this, "PREF_CHECK_COMPATIBILITY", function () {
|
||||
#endif
|
||||
});
|
||||
|
||||
const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility";
|
||||
// Note: This has to be kept in sync with the same constant in AddonManager.jsm
|
||||
const STRICT_COMPATIBILITY_DEFAULT = true;
|
||||
|
||||
const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
|
||||
|
||||
const API_VERSION = "1.5";
|
||||
@ -81,7 +86,9 @@ const DEFAULT_CACHE_TYPES = "extension,theme,locale,dictionary";
|
||||
|
||||
const KEY_PROFILEDIR = "ProfD";
|
||||
const FILE_DATABASE = "addons.sqlite";
|
||||
const DB_SCHEMA = 2;
|
||||
const DB_SCHEMA = 3;
|
||||
|
||||
const TOOLKIT_ID = "toolkit@mozilla.org";
|
||||
|
||||
["LOG", "WARN", "ERROR"].forEach(function(aName) {
|
||||
this.__defineGetter__(aName, function() {
|
||||
@ -356,6 +363,12 @@ AddonSearchResult.prototype = {
|
||||
*/
|
||||
isPlatformCompatible: true,
|
||||
|
||||
/**
|
||||
* Array of AddonCompatibilityOverride objects, that describe overrides for
|
||||
* compatibility with an application versions.
|
||||
**/
|
||||
compatibilityOverrides: null,
|
||||
|
||||
/**
|
||||
* True if the add-on has a secure means of updating
|
||||
*/
|
||||
@ -609,8 +622,8 @@ var AddonRepository = {
|
||||
getAddonsToCache(aIds, function(aAddons) {
|
||||
// Completely remove cache if there are no add-ons to cache
|
||||
if (aAddons.length == 0) {
|
||||
this._addons = null;
|
||||
this._pendingCallbacks = null;
|
||||
self._addons = null;
|
||||
self._pendingCallbacks = null;
|
||||
AddonDatabase.delete(aCallback);
|
||||
return;
|
||||
}
|
||||
@ -744,12 +757,12 @@ var AddonRepository = {
|
||||
let url = this._formatURLPref(PREF_GETADDONS_BYIDS, params);
|
||||
|
||||
let self = this;
|
||||
function handleResults(aElements, aTotalResults) {
|
||||
function 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 < self._maxResults; i++) {
|
||||
let result = self._parseAddon(aElements[i]);
|
||||
let result = self._parseAddon(aElements[i], null, aCompatData);
|
||||
if (result == null)
|
||||
continue;
|
||||
|
||||
@ -763,6 +776,24 @@ var AddonRepository = {
|
||||
ids.splice(idIndex, 1);
|
||||
}
|
||||
|
||||
// Include any compatibility overrides for addons not hosted by the
|
||||
// remote repository.
|
||||
for each (let addonCompat in aCompatData) {
|
||||
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: addon,
|
||||
xpiURL: null,
|
||||
xpiHash: null
|
||||
};
|
||||
results.push(result);
|
||||
}
|
||||
|
||||
// aTotalResults irrelevant
|
||||
self._reportSuccess(results, -1);
|
||||
}
|
||||
@ -865,6 +896,14 @@ var AddonRepository = {
|
||||
return (elementsList.length == 1) ? elementsList[0] : null;
|
||||
},
|
||||
|
||||
// Get direct descendant by unique tag name.
|
||||
// Returns null if not unique tag name.
|
||||
_getUniqueDirectDescendant: function(aElement, aTagName) {
|
||||
let elementsList = Array.filter(aElement.children,
|
||||
function(aChild) aChild.tagName == aTagName);
|
||||
return (elementsList.length == 1) ? elementsList[0] : null;
|
||||
},
|
||||
|
||||
// Parse out trimmed text content. Returns null if text content empty.
|
||||
_getTextContent: function(aElement) {
|
||||
let textContent = aElement.textContent.trim();
|
||||
@ -878,6 +917,14 @@ var AddonRepository = {
|
||||
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: function(aElement, aTagName) {
|
||||
let descendant = this._getUniqueDirectDescendant(aElement, aTagName);
|
||||
return (descendant != null) ? this._getTextContent(descendant) : null;
|
||||
},
|
||||
|
||||
/*
|
||||
* Creates an AddonSearchResult by parsing an <addon> element
|
||||
*
|
||||
@ -885,10 +932,13 @@ var AddonRepository = {
|
||||
* The <addon> 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.
|
||||
*/
|
||||
_parseAddon: function(aElement, aSkip) {
|
||||
_parseAddon: function(aElement, aSkip, aCompatData) {
|
||||
let skipIDs = (aSkip && aSkip.ids) ? aSkip.ids : [];
|
||||
let skipSourceURIs = (aSkip && aSkip.sourceURIs) ? aSkip.sourceURIs : [];
|
||||
|
||||
@ -903,6 +953,9 @@ var AddonRepository = {
|
||||
xpiHash: null
|
||||
};
|
||||
|
||||
if (aCompatData && guid in aCompatData)
|
||||
addon.compatibilityOverrides = aCompatData[guid].compatRanges;
|
||||
|
||||
let self = this;
|
||||
for (let node = aElement.firstChild; node; node = node.nextSibling) {
|
||||
if (!(node instanceof Ci.nsIDOMElement))
|
||||
@ -1095,6 +1148,11 @@ var AddonRepository = {
|
||||
checkCompatibility = Services.prefs.getBoolPref(PREF_CHECK_COMPATIBILITY);
|
||||
} catch(e) { }
|
||||
|
||||
let strictCompatibility = STRICT_COMPATIBILITY_DEFAULT;
|
||||
try {
|
||||
strictCompatibility = Services.prefs.getBoolPref(PREF_EM_STRICT_COMPATIBILITY);
|
||||
} catch (e) {}
|
||||
|
||||
function isSameApplication(aAppNode) {
|
||||
return self._getTextContent(aAppNode) == Services.appinfo.ID;
|
||||
}
|
||||
@ -1119,7 +1177,8 @@ var AddonRepository = {
|
||||
|
||||
let currentVersion = Services.appinfo.version;
|
||||
return (Services.vc.compare(minVersion, currentVersion) <= 0 &&
|
||||
Services.vc.compare(currentVersion, maxVersion) <= 0);
|
||||
((!strictCompatibility) ||
|
||||
Services.vc.compare(currentVersion, maxVersion) <= 0));
|
||||
});
|
||||
|
||||
// Ignore add-ons not compatible with this Application
|
||||
@ -1131,7 +1190,9 @@ var AddonRepository = {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add-on meets all requirements, so parse out data
|
||||
// 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;
|
||||
@ -1186,6 +1247,83 @@ var AddonRepository = {
|
||||
});
|
||||
},
|
||||
|
||||
// Parses addon_compatibility nodes, that describe compatibility overrides.
|
||||
_parseAddonCompatElement: function(aResultObj, aElement) {
|
||||
let guid = this._getDescendantTextContent(aElement, "guid");
|
||||
if (!guid)
|
||||
return;
|
||||
|
||||
let compat = {id: guid};
|
||||
compat.hosted = aElement.getAttribute("hosted") != "false";
|
||||
|
||||
function findMatchingAppRange(aNodes) {
|
||||
let toolkitAppRange = null;
|
||||
for (let i = 0; i < aNodes.length; i++) {
|
||||
let node = aNodes[i];
|
||||
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: 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")
|
||||
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 || !override.maxVersion)
|
||||
return null;
|
||||
|
||||
let appRanges = aNode.querySelectorAll("compatible_applications > application");
|
||||
let appRange = findMatchingAppRange.bind(this)(appRanges);
|
||||
if (!appRange)
|
||||
return null;
|
||||
|
||||
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(function(aItem) !!aItem);
|
||||
if (compat.compatRanges.length == 0)
|
||||
return;
|
||||
|
||||
aResultObj[compat.id] = compat;
|
||||
},
|
||||
|
||||
// Parses addon_compatibility elements.
|
||||
_parseAddonCompatData: function(aElements) {
|
||||
let compatData = {};
|
||||
Array.forEach(aElements, this._parseAddonCompatElement.bind(this, compatData));
|
||||
return compatData;
|
||||
},
|
||||
|
||||
// Begins a new search if one isn't currently executing
|
||||
_beginSearch: function(aURI, aMaxResults, aCallback, aHandleResults) {
|
||||
if (this._searching || aURI == null || aMaxResults <= 0) {
|
||||
@ -1227,7 +1365,10 @@ var AddonRepository = {
|
||||
if (parsedTotalResults >= totalResults)
|
||||
totalResults = parsedTotalResults;
|
||||
|
||||
aHandleResults(elements, totalResults);
|
||||
let compatElements = documentElement.getElementsByTagName("addon_compatibility");
|
||||
let compatData = self._parseAddonCompatData(compatElements);
|
||||
|
||||
aHandleResults(elements, totalResults, compatData);
|
||||
}, false);
|
||||
this._request.send(null);
|
||||
},
|
||||
@ -1271,7 +1412,31 @@ var AddonRepository = {
|
||||
});
|
||||
|
||||
return Services.urlFormatter.formatURL(url);
|
||||
},
|
||||
|
||||
// Find a AddonCompatibilityOverride that matches a given aAddonVersion and
|
||||
// application/platform version.
|
||||
findMatchingCompatOverride: function AR_findMatchingCompatOverride(aAddonVersion,
|
||||
aCompatOverrides) {
|
||||
for (let i = 0; i < aCompatOverrides.length; i++) {
|
||||
let override = aCompatOverrides[i];
|
||||
|
||||
let appVersion = null;
|
||||
if (override.appID == TOOLKIT_ID)
|
||||
appVersion = Services.appinfo.platformVersion;
|
||||
else
|
||||
appVersion = Services.appinfo.version;
|
||||
|
||||
if (Services.vc.compare(override.minVersion, aAddonVersion) <= 0 &&
|
||||
Services.vc.compare(aAddonVersion, override.maxVersion) <= 0 &&
|
||||
Services.vc.compare(override.appMinVersion, appVersion) <= 0 &&
|
||||
Services.vc.compare(appVersion, override.appMaxVersion) <= 0) {
|
||||
return override;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
AddonRepository.initialize();
|
||||
|
||||
@ -1300,6 +1465,11 @@ var AddonDatabase = {
|
||||
"thumbnailURL, thumbnailWidth, thumbnailHeight, caption " +
|
||||
"FROM screenshot ORDER BY addon_internal_id, num",
|
||||
|
||||
getAllCompatOverrides: "SELECT addon_internal_id, type, minVersion, " +
|
||||
"maxVersion, appID, appMinVersion, appMaxVersion " +
|
||||
"FROM compatibility_override " +
|
||||
"ORDER BY addon_internal_id, num",
|
||||
|
||||
insertAddon: "INSERT INTO addon VALUES (NULL, :id, :type, :name, :version, " +
|
||||
":creator, :creatorURL, :description, :fullDescription, " +
|
||||
":developerComments, :eula, :iconURL, :homepageURL, :supportURL, " +
|
||||
@ -1319,6 +1489,11 @@ var AddonDatabase = {
|
||||
":num, :url, :width, :height, :thumbnailURL, " +
|
||||
":thumbnailWidth, :thumbnailHeight, :caption)",
|
||||
|
||||
insertCompatibilityOverride: "INSERT INTO compatibility_override VALUES " +
|
||||
"(:addon_internal_id, :num, :type, " +
|
||||
":minVersion, :maxVersion, :appID, " +
|
||||
":appMinVersion, :appMaxVersion)",
|
||||
|
||||
emptyAddon: "DELETE FROM addon"
|
||||
},
|
||||
|
||||
@ -1384,29 +1559,42 @@ var AddonDatabase = {
|
||||
if (dbMissing)
|
||||
this._createSchema();
|
||||
|
||||
switch (this.connection.schemaVersion) {
|
||||
case 0:
|
||||
this._createSchema();
|
||||
break;
|
||||
case 1:
|
||||
try {
|
||||
try {
|
||||
switch (this.connection.schemaVersion) {
|
||||
case 0:
|
||||
LOG("Recreating database schema");
|
||||
this._createSchema();
|
||||
break;
|
||||
case 1:
|
||||
LOG("Upgrading database schema");
|
||||
this.connection.executeSimpleSQL("ALTER TABLE screenshot ADD COLUMN width INTEGER");
|
||||
this.connection.executeSimpleSQL("ALTER TABLE screenshot ADD COLUMN height INTEGER");
|
||||
this.connection.executeSimpleSQL("ALTER TABLE screenshot ADD COLUMN thumbnailWidth INTEGER");
|
||||
this.connection.executeSimpleSQL("ALTER TABLE screenshot ADD COLUMN thumbnailHeight INTEGER");
|
||||
this._createIndices();
|
||||
this.connection.schemaVersion = DB_SCHEMA;
|
||||
} catch (e) {
|
||||
ERROR("Failed to create database schema", e);
|
||||
this.logSQLError(this.connection.lastError, this.connection.lastErrorString);
|
||||
this.connection.rollbackTransaction();
|
||||
case 2:
|
||||
this.connection.createTable("compatibility_override",
|
||||
"addon_internal_id INTEGER, " +
|
||||
"num INTEGER, " +
|
||||
"type TEXT, " +
|
||||
"minVersion TEXT, " +
|
||||
"maxVersion TEXT, " +
|
||||
"appID TEXT, " +
|
||||
"appMinVersion TEXT, " +
|
||||
"appMaxVersion TEXT, " +
|
||||
"PRIMARY KEY (addon_internal_id, num)");
|
||||
this._createIndices();
|
||||
this._createTriggers();
|
||||
this.connection.schemaVersion = DB_SCHEMA;
|
||||
case 3:
|
||||
break;
|
||||
default:
|
||||
return tryAgain();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
default:
|
||||
return tryAgain();
|
||||
}
|
||||
} catch (e) {
|
||||
ERROR("Failed to create database schema", e);
|
||||
this.logSQLError(this.connection.lastError, this.connection.lastErrorString);
|
||||
this.connection.rollbackTransaction();
|
||||
return tryAgain();
|
||||
}
|
||||
|
||||
return this.connection;
|
||||
@ -1595,6 +1783,38 @@ var AddonDatabase = {
|
||||
return;
|
||||
}
|
||||
|
||||
getAllCompatOverrides();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getAllCompatOverrides() {
|
||||
self.getAsyncStatement("getAllCompatOverrides").executeAsync({
|
||||
handleResult: function(aResults) {
|
||||
let row = null;
|
||||
while (row = aResults.getNextRow()) {
|
||||
let addon_internal_id = row.getResultByName("addon_internal_id");
|
||||
if (!(addon_internal_id in addons)) {
|
||||
WARN("Found a compatibility override not linked to an add-on in database");
|
||||
continue;
|
||||
}
|
||||
|
||||
let addon = addons[addon_internal_id];
|
||||
if (!addon.compatibilityOverrides)
|
||||
addon.compatibilityOverrides = [];
|
||||
addon.compatibilityOverrides.push(self._makeCompatOverrideFromAsyncRow(row));
|
||||
}
|
||||
},
|
||||
|
||||
handleError: self.asyncErrorLogger,
|
||||
|
||||
handleCompletion: function(aReason) {
|
||||
if (aReason != Ci.mozIStorageStatementCallback.REASON_FINISHED) {
|
||||
ERROR("Error retrieving compatibility overrides from database. Returning empty results");
|
||||
aCallback({});
|
||||
return;
|
||||
}
|
||||
|
||||
let returnedAddons = {};
|
||||
for each (let addon in addons)
|
||||
returnedAddons[addon.id] = addon;
|
||||
@ -1677,8 +1897,9 @@ var AddonDatabase = {
|
||||
let internal_id = null;
|
||||
this.connection.beginTransaction();
|
||||
|
||||
// Simultaneously insert the developers and screenshots of the add-on
|
||||
function insertDevelopersAndScreenshots() {
|
||||
// Simultaneously insert the developers, screenshots, and compatibility
|
||||
// overrides of the add-on.
|
||||
function insertAdditionalData() {
|
||||
let stmts = [];
|
||||
|
||||
// Initialize statement and parameters for inserting an array
|
||||
@ -1696,11 +1917,15 @@ var AddonDatabase = {
|
||||
stmts.push(stmt);
|
||||
}
|
||||
|
||||
// Initialize statements to insert developers and screenshots
|
||||
// Initialize statements to insert developers, screenshots, and
|
||||
// compatibility overrides
|
||||
initializeArrayInsert("insertDeveloper", aAddon.developers,
|
||||
self._addDeveloperParams);
|
||||
initializeArrayInsert("insertScreenshot", aAddon.screenshots,
|
||||
self._addScreenshotParams);
|
||||
initializeArrayInsert("insertCompatibilityOverride",
|
||||
aAddon.compatibilityOverrides,
|
||||
self._addCompatOverrideParams);
|
||||
|
||||
// Immediately call callback if nothing to insert
|
||||
if (stmts.length == 0) {
|
||||
@ -1714,7 +1939,7 @@ var AddonDatabase = {
|
||||
handleError: self.asyncErrorLogger,
|
||||
handleCompletion: function(aReason) {
|
||||
if (aReason != Ci.mozIStorageStatementCallback.REASON_FINISHED) {
|
||||
ERROR("Error inserting developers and screenshots into database. Attempting to continue");
|
||||
ERROR("Error inserting additional addon metadata into database. Attempting to continue");
|
||||
self.connection.rollbackTransaction();
|
||||
}
|
||||
else {
|
||||
@ -1740,7 +1965,7 @@ var AddonDatabase = {
|
||||
}
|
||||
|
||||
internal_id = self.connection.lastInsertRowID;
|
||||
insertDevelopersAndScreenshots();
|
||||
insertAdditionalData();
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -1826,6 +2051,35 @@ var AddonDatabase = {
|
||||
aParams.addParams(bp);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add compatibility override parameters to the specified
|
||||
* mozIStorageBindingParamsArray.
|
||||
*
|
||||
* @param aParams
|
||||
* The mozIStorageBindingParamsArray to add the parameters to
|
||||
* @param aInternalID
|
||||
* The internal_id of the add-on that this override is for
|
||||
* @param aOverride
|
||||
* The override to make the parameters from
|
||||
* @param aIndex
|
||||
* The index of this override
|
||||
*/
|
||||
_addCompatOverrideParams: function AD_addCompatOverrideParams(aParams,
|
||||
aInternalID,
|
||||
aOverride,
|
||||
aIndex) {
|
||||
let bp = aParams.newBindingParams();
|
||||
bp.bindByName("addon_internal_id", aInternalID);
|
||||
bp.bindByName("num", aIndex);
|
||||
bp.bindByName("type", aOverride.type);
|
||||
bp.bindByName("minVersion", aOverride.minVersion);
|
||||
bp.bindByName("maxVersion", aOverride.maxVersion);
|
||||
bp.bindByName("appID", aOverride.appID);
|
||||
bp.bindByName("appMinVersion", aOverride.appMinVersion);
|
||||
bp.bindByName("appMaxVersion", aOverride.appMaxVersion);
|
||||
aParams.addParams(bp);
|
||||
},
|
||||
|
||||
/**
|
||||
* Make add-on from an asynchronous row
|
||||
* Note: This add-on will be lacking both developers and screenshots
|
||||
@ -1894,6 +2148,28 @@ var AddonDatabase = {
|
||||
thumbnailWidth, thumbnailHeight, caption);
|
||||
},
|
||||
|
||||
/**
|
||||
* Make a CompatibilityOverride from an asynchronous row
|
||||
*
|
||||
* @param aRow
|
||||
* The asynchronous row to use
|
||||
* @return The created CompatibilityOverride
|
||||
*/
|
||||
_makeCompatOverrideFromAsyncRow: function AD_makeCompatOverrideFromAsyncRow(aRow) {
|
||||
let type = aRow.getResultByName("type");
|
||||
let minVersion = aRow.getResultByName("minVersion");
|
||||
let maxVersion = aRow.getResultByName("maxVersion");
|
||||
let appID = aRow.getResultByName("appID");
|
||||
let appMinVersion = aRow.getResultByName("appMinVersion");
|
||||
let appMaxVersion = aRow.getResultByName("appMaxVersion");
|
||||
return new AddonManagerPrivate.AddonCompatibilityOverride(type,
|
||||
minVersion,
|
||||
maxVersion,
|
||||
appID,
|
||||
appMinVersion,
|
||||
appMaxVersion);
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously creates the schema in the database.
|
||||
*/
|
||||
@ -1950,13 +2226,19 @@ var AddonDatabase = {
|
||||
"caption TEXT, " +
|
||||
"PRIMARY KEY (addon_internal_id, num)");
|
||||
|
||||
this._createIndices();
|
||||
this.connection.createTable("compatibility_override",
|
||||
"addon_internal_id INTEGER, " +
|
||||
"num INTEGER, " +
|
||||
"type TEXT, " +
|
||||
"minVersion TEXT, " +
|
||||
"maxVersion TEXT, " +
|
||||
"appID TEXT, " +
|
||||
"appMinVersion TEXT, " +
|
||||
"appMaxVersion TEXT, " +
|
||||
"PRIMARY KEY (addon_internal_id, num)");
|
||||
|
||||
this.connection.executeSimpleSQL("CREATE TRIGGER delete_addon AFTER DELETE " +
|
||||
"ON addon BEGIN " +
|
||||
"DELETE FROM developer WHERE addon_internal_id=old.internal_id; " +
|
||||
"DELETE FROM screenshot WHERE addon_internal_id=old.internal_id; " +
|
||||
"END");
|
||||
this._createIndices();
|
||||
this._createTriggers();
|
||||
|
||||
this.connection.schemaVersion = DB_SCHEMA;
|
||||
this.connection.commitTransaction();
|
||||
@ -1968,6 +2250,19 @@ var AddonDatabase = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously creates the triggers in the database.
|
||||
*/
|
||||
_createTriggers: function AD__createTriggers() {
|
||||
this.connection.executeSimpleSQL("DROP TRIGGER IF EXISTS delete_addon");
|
||||
this.connection.executeSimpleSQL("CREATE TRIGGER delete_addon AFTER DELETE " +
|
||||
"ON addon BEGIN " +
|
||||
"DELETE FROM developer WHERE addon_internal_id=old.internal_id; " +
|
||||
"DELETE FROM screenshot WHERE addon_internal_id=old.internal_id; " +
|
||||
"DELETE FROM compatibility_override WHERE addon_internal_id=old.internal_id; " +
|
||||
"END");
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously creates the indices in the database.
|
||||
*/
|
||||
@ -1976,5 +2271,7 @@ var AddonDatabase = {
|
||||
"ON developer (addon_internal_id)");
|
||||
this.connection.executeSimpleSQL("CREATE INDEX IF NOT EXISTS screenshot_idx " +
|
||||
"ON screenshot (addon_internal_id)");
|
||||
this.connection.executeSimpleSQL("CREATE INDEX IF NOT EXISTS compatibility_override_idx " +
|
||||
"ON compatibility_override (addon_internal_id)");
|
||||
}
|
||||
};
|
||||
|
@ -3346,6 +3346,36 @@ var XPIProvider = {
|
||||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the repositoryAddon property for all add-ons.
|
||||
*
|
||||
* @param aCallback
|
||||
* Function to call when operation is complete.
|
||||
*/
|
||||
updateAddonRepositoryData: function XPI_updateAddonRepositoryData(aCallback) {
|
||||
let self = this;
|
||||
XPIDatabase.getVisibleAddons(null, function UARD_getVisibleAddonsCallback(aAddons) {
|
||||
let pending = aAddons.length;
|
||||
function notifyComplete() {
|
||||
if (--pending == 0)
|
||||
aCallback();
|
||||
}
|
||||
|
||||
aAddons.forEach(function UARD_forEachCallback(aAddon) {
|
||||
AddonRepository.getCachedAddonByID(aAddon.id,
|
||||
function UARD_getCachedAddonCallback(aRepoAddon) {
|
||||
if (aRepoAddon) {
|
||||
aAddon._repositoryAddon = aRepoAddon;
|
||||
aAddon.compatibilityOverrides = aRepoAddon.compatibilityOverrides;
|
||||
self.updateAddonDisabledState(aAddon);
|
||||
}
|
||||
|
||||
notifyComplete();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* When the previously selected theme is removed this method will be called
|
||||
* to enable the default theme.
|
||||
@ -4052,6 +4082,9 @@ AsyncAddonListCallback.prototype = {
|
||||
XPIDatabase.makeAddonFromRowAsync(row, function(aAddon) {
|
||||
function completeAddon(aRepositoryAddon) {
|
||||
aAddon._repositoryAddon = aRepositoryAddon;
|
||||
aAddon.compatibilityOverrides = aRepositoryAddon ?
|
||||
aRepositoryAddon.compatibilityOverrides :
|
||||
null;
|
||||
self.addons.push(aAddon);
|
||||
if (self.complete && self.addons.length == self.count)
|
||||
self.callback(self.addons);
|
||||
@ -6152,6 +6185,7 @@ AddonInstall.prototype = {
|
||||
AddonRepository.getCachedAddonByID(aAddon.id, function(aRepoAddon) {
|
||||
if (aRepoAddon) {
|
||||
aAddon._repositoryAddon = aRepoAddon;
|
||||
aAddon.compatibilityOverrides = aRepoAddon.compatibilityOverrides;
|
||||
aCallback();
|
||||
return;
|
||||
}
|
||||
@ -6160,6 +6194,9 @@ AddonInstall.prototype = {
|
||||
AddonRepository.cacheAddons([aAddon.id], function() {
|
||||
AddonRepository.getCachedAddonByID(aAddon.id, function(aRepoAddon) {
|
||||
aAddon._repositoryAddon = aRepoAddon;
|
||||
aAddon.compatibilityOverrides = aRepoAddon ?
|
||||
aRepoAddon.compatibilityOverrides :
|
||||
null;
|
||||
aCallback();
|
||||
});
|
||||
});
|
||||
@ -7149,6 +7186,17 @@ AddonInternal.prototype = {
|
||||
if (this.type == "extension" && !AddonManager.strictCompatibility &&
|
||||
!this.strictCompatibility && !this.hasBinaryComponents) {
|
||||
|
||||
// The repository can specify compatibility overrides.
|
||||
// Note: For now, only blacklisting is supported by overrides.
|
||||
if (this._repositoryAddon &&
|
||||
this._repositoryAddon.compatibilityOverrides) {
|
||||
let overrides = this._repositoryAddon.compatibilityOverrides;
|
||||
let override = AddonRepository.findMatchingCompatOverride(this.version,
|
||||
overrides);
|
||||
if (override && override.type == "incompatible")
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extremely old extensions should not be compatible by default.
|
||||
let minCompatVersion;
|
||||
if (app.id == Services.appinfo.ID)
|
||||
@ -7252,7 +7300,7 @@ AddonInternal.prototype = {
|
||||
importMetadata: function(aObj) {
|
||||
["targetApplications", "userDisabled", "softDisabled", "existingAddonID",
|
||||
"sourceURI", "releaseNotesURI", "installDate", "updateDate",
|
||||
"applyBackgroundUpdates"].forEach(function(aProp) {
|
||||
"applyBackgroundUpdates", "compatibilityOverrides"].forEach(function(aProp) {
|
||||
if (!(aProp in aObj))
|
||||
return;
|
||||
|
||||
@ -7368,7 +7416,7 @@ function AddonWrapper(aAddon) {
|
||||
["id", "syncGUID", "version", "type", "isCompatible", "isPlatformCompatible",
|
||||
"providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled",
|
||||
"softDisabled", "skinnable", "size", "foreignInstall", "hasBinaryComponents",
|
||||
"strictCompatibility"].forEach(function(aProp) {
|
||||
"strictCompatibility", "compatibilityOverrides"].forEach(function(aProp) {
|
||||
this.__defineGetter__(aProp, function() aAddon[aProp]);
|
||||
}, this);
|
||||
|
||||
|
@ -39,6 +39,7 @@ function test() {
|
||||
requestLongerTimeout(2);
|
||||
// Turn on searching for this test
|
||||
Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 15);
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
@ -621,6 +622,28 @@ add_test(function() {
|
||||
});
|
||||
});
|
||||
|
||||
// Tests that compatible-by-default addons are shown if strict compatibility checking is disabled
|
||||
add_test(function() {
|
||||
restart_manager(gManagerWindow, null, function(aWindow) {
|
||||
gManagerWindow = aWindow;
|
||||
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, false);
|
||||
search("incompatible", false, function() {
|
||||
var item = get_addon_item("remote5");
|
||||
is_element_visible(item, "Incompatible addon should be visible");
|
||||
isnot(item.getAttribute("notification"), "warning", "Compatibility warning should not be shown");
|
||||
|
||||
var item = get_addon_item("remote6");
|
||||
is(item, null, "Addon incompatible with the product should not be visible");
|
||||
|
||||
Services.prefs.setBoolPref(PREF_STRICT_COMPAT, true);
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Tests that restarting the manager doesn't change search results
|
||||
add_test(function() {
|
||||
restart_manager(gManagerWindow, null, function(aWindow) {
|
||||
|
@ -115,5 +115,68 @@
|
||||
</preview>
|
||||
</previews>
|
||||
</addon>
|
||||
|
||||
<addon_compatibility hosted="true" id="123">
|
||||
<guid>test_AddonRepository_1@tests.mozilla.org</guid>
|
||||
<name>PASS</name>
|
||||
<version_ranges>
|
||||
<!-- Will be included -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.2</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>3.0</min_version>
|
||||
<max_version>4.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Will be included -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.2</min_version>
|
||||
<max_version>0.3</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>5.0</min_version>
|
||||
<max_version>6.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Won't be included - invalid type attribute -->
|
||||
<version_range type="unknown">
|
||||
<min_version>9</min_version>
|
||||
<max_version>10</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>10.0</min_version>
|
||||
<max_version>11.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Won't be included - no matching appID -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.2</min_version>
|
||||
<max_version>0.3</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>Unknown App</name>
|
||||
<application_id>123</application_id>
|
||||
<min_version>1.0</min_version>
|
||||
<max_version>999.0</max_version>
|
||||
<appID>unknown-app@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
</searchresults>
|
||||
|
||||
|
@ -62,6 +62,69 @@
|
||||
<install size="5555">http://localhost:4444/addons/test_AddonRepository_2.xpi</install>
|
||||
</addon>
|
||||
|
||||
<addon_compatibility hosted="true" id="123">
|
||||
<guid>test1@tests.mozilla.org</guid>
|
||||
<name>PASS</name>
|
||||
<version_ranges>
|
||||
<!-- Will be included -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.2</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>3.0</min_version>
|
||||
<max_version>4.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Will be included -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.2</min_version>
|
||||
<max_version>0.3</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>5.0</min_version>
|
||||
<max_version>6.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Won't be included - invalid type attribute -->
|
||||
<version_range type="unknown">
|
||||
<min_version>9</min_version>
|
||||
<max_version>10</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<application_id>666</application_id>
|
||||
<min_version>10.0</min_version>
|
||||
<max_version>11.0</max_version>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<!-- Won't be included - no matching appID -->
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.2</min_version>
|
||||
<max_version>0.3</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>Unknown App</name>
|
||||
<application_id>123</application_id>
|
||||
<min_version>1.0</min_version>
|
||||
<max_version>999.0</max_version>
|
||||
<appID>unknown-app@tests.mozilla.org</appID>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<!-- Fails because guid matches previously successful result -->
|
||||
<addon>
|
||||
<name>FAIL</name>
|
||||
|
@ -0,0 +1,228 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<searchresults total_results="9">
|
||||
<addon>
|
||||
<name>Test addon 2</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon2@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 3</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon3@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 3</name>
|
||||
<guid>addon3@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.9</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 4</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon4@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 4</name>
|
||||
<guid>addon4@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.9</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 5</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon5@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 5</name>
|
||||
<guid>addon5@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.9</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>Unknown App</name>
|
||||
<appID>unknown-app@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 6</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon6@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 6</name>
|
||||
<guid>addon6@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>0.9</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 7</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon7@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 7</name>
|
||||
<guid>addon7@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.9</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon>
|
||||
<name>Test addon 8</name>
|
||||
<type id="1">Extension</type>
|
||||
<guid>addon8@tests.mozilla.org</guid>
|
||||
<version>1.0</version>
|
||||
</addon>
|
||||
<addon_compatibility hosted="true">
|
||||
<name>Test addon 8</name>
|
||||
<guid>addon8@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>6</min_version>
|
||||
<max_version>6.2</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>0.9</min_version>
|
||||
<max_version>9</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>9</max_version>
|
||||
</application>
|
||||
<application>
|
||||
<name>Unknown app</name>
|
||||
<appID>unknown-app@tests.mozilla.org</appID>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>9</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.2</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>0.1</min_version>
|
||||
<max_version>0.9</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon_compatibility hosted="false">
|
||||
<name>Test addon 9</name>
|
||||
<guid>addon9@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="incompatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
<addon_compatibility hosted="false">
|
||||
<name>Test addon 10</name>
|
||||
<guid>addon10@tests.mozilla.org</guid>
|
||||
<version_ranges>
|
||||
<version_range type="compatible">
|
||||
<min_version>0.5</min_version>
|
||||
<max_version>1.0</max_version>
|
||||
<compatible_applications>
|
||||
<application>
|
||||
<name>XPCShell</name>
|
||||
<appID>xpcshell@tests.mozilla.org</appID>
|
||||
<min_version>1</min_version>
|
||||
<max_version>2</max_version>
|
||||
</application>
|
||||
</compatible_applications>
|
||||
</version_range>
|
||||
</version_ranges>
|
||||
</addon_compatibility>
|
||||
|
||||
</searchresults>
|
@ -244,6 +244,12 @@ function do_check_addon(aActualAddon, aExpectedAddon, aProperties) {
|
||||
do_check_eq(actualValue.getTime(), expectedValue.getTime());
|
||||
break;
|
||||
|
||||
case "compatibilityOverrides":
|
||||
do_check_eq(actualValue.length, expectedValue.length);
|
||||
for (let i = 0; i < actualValue.length; i++)
|
||||
do_check_compatibilityoverride(actualValue[i], expectedValue[i]);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (actualValue !== expectedValue)
|
||||
do_throw("Failed for " + aProperty + " for add-on " + aExpectedAddon.id +
|
||||
@ -285,6 +291,24 @@ function do_check_screenshot(aActual, aExpected) {
|
||||
do_check_eq(aActual.caption, aExpected.caption);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the actual compatibility override is the same as the expected
|
||||
* compatibility override.
|
||||
*
|
||||
* @param aAction
|
||||
* The actual compatibility override to check.
|
||||
* @param aExpected
|
||||
* The expected compatibility override to check against.
|
||||
*/
|
||||
function do_check_compatibilityoverride(aActual, aExpected) {
|
||||
do_check_eq(aActual.type, aExpected.type);
|
||||
do_check_eq(aActual.minVersion, aExpected.minVersion);
|
||||
do_check_eq(aActual.maxVersion, aExpected.maxVersion);
|
||||
do_check_eq(aActual.appID, aExpected.appID);
|
||||
do_check_eq(aActual.appMinVersion, aExpected.appMinVersion);
|
||||
do_check_eq(aActual.appMaxVersion, aExpected.appMaxVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts up the add-on manager as if it was started by the application.
|
||||
*
|
||||
|
@ -36,7 +36,8 @@ var ADDON_PROPERTIES = ["id", "type", "version", "creator", "developers",
|
||||
"averageRating", "reviewCount", "reviewURL",
|
||||
"totalDownloads", "weeklyDownloads", "dailyUsers",
|
||||
"sourceURI", "repositoryStatus", "size", "updateDate",
|
||||
"purchaseURL", "purchaseAmount", "purchaseDisplayAmount"];
|
||||
"purchaseURL", "purchaseAmount", "purchaseDisplayAmount",
|
||||
"compatibilityOverrides"];
|
||||
|
||||
// Results of getAddonsByIDs
|
||||
var GET_RESULTS = [{
|
||||
@ -82,7 +83,22 @@ var GET_RESULTS = [{
|
||||
sourceURI: BASE_URL + INSTALL_URL2,
|
||||
repositoryStatus: 8,
|
||||
size: 5555,
|
||||
updateDate: new Date(1265033045000)
|
||||
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",
|
||||
version: "1.4",
|
||||
@ -176,7 +192,8 @@ var SEARCH_RESULTS = [{
|
||||
sourceURI: BASE_URL + "/test3.xpi",
|
||||
repositoryStatus: 8,
|
||||
size: 5555,
|
||||
updateDate: new Date(1265033045000)
|
||||
updateDate: new Date(1265033045000),
|
||||
|
||||
}, {
|
||||
id: "purchase1@tests.mozilla.org",
|
||||
type: "extension",
|
||||
|
@ -39,7 +39,8 @@ const ADDON_PROPERTIES = ["id", "type", "name", "version", "creator",
|
||||
"optionsURL", "aboutURL", "contributionURL",
|
||||
"contributionAmount", "averageRating", "reviewCount",
|
||||
"reviewURL", "totalDownloads", "weeklyDownloads",
|
||||
"dailyUsers", "sourceURI", "repositoryStatus"];
|
||||
"dailyUsers", "sourceURI", "repositoryStatus",
|
||||
"compatibilityOverrides"];
|
||||
|
||||
// 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
|
||||
@ -90,7 +91,22 @@ const REPOSITORY_ADDONS = [{
|
||||
weeklyDownloads: 3331,
|
||||
dailyUsers: 4441,
|
||||
sourceURI: BASE_URL + "/repo/1/install.xpi",
|
||||
repositoryStatus: 4
|
||||
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",
|
||||
@ -222,7 +238,22 @@ const WITH_CACHE = [{
|
||||
weeklyDownloads: 3331,
|
||||
dailyUsers: 4441,
|
||||
sourceURI: NetUtil.newURI(ADDON_FILES[0]).spec,
|
||||
repositoryStatus: 4
|
||||
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",
|
||||
@ -319,7 +350,22 @@ const WITH_EXTENSION_CACHE = [{
|
||||
weeklyDownloads: 3331,
|
||||
dailyUsers: 4441,
|
||||
sourceURI: NetUtil.newURI(ADDON_FILES[0]).spec,
|
||||
repositoryStatus: 4
|
||||
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",
|
||||
|
275
toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js
Normal file
275
toolkit/mozapps/extensions/test/xpcshell/test_compatoverrides.js
Normal file
@ -0,0 +1,275 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests compatibility overrides, for when strict compatibility checking is
|
||||
// disabled. See bug 693906.
|
||||
|
||||
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
|
||||
const PORT = 4444;
|
||||
const BASE_URL = "http://localhost:" + PORT;
|
||||
const DEFAULT_URL = "about:blank";
|
||||
const REQ_URL = "/data.xml";
|
||||
|
||||
Services.prefs.setBoolPref(PREF_EM_STRICT_COMPATIBILITY, false);
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
Services.prefs.setCharPref(PREF_GETADDONS_BYIDS,
|
||||
BASE_URL + REQ_URL);
|
||||
|
||||
do_load_httpd_js();
|
||||
var gServer;
|
||||
|
||||
|
||||
// Not hosted, no overrides
|
||||
var addon1 = {
|
||||
id: "addon1@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 1",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, no overrides
|
||||
var addon2 = {
|
||||
id: "addon2@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 2",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, matching override
|
||||
var addon3 = {
|
||||
id: "addon3@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 3",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, matching override, wouldn't be compatible if strict chekcing is enabled
|
||||
var addon4 = {
|
||||
id: "addon4@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 4",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "0.1",
|
||||
maxVersion: "0.2"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, app ID doesn't match in override
|
||||
var addon5 = {
|
||||
id: "addon5@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 5",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, addon version range doesn't match in override
|
||||
var addon6 = {
|
||||
id: "addon6@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 6",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, app version range doesn't match in override
|
||||
var addon7 = {
|
||||
id: "addon7@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 7",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Hosted, multiple overrides
|
||||
var addon8 = {
|
||||
id: "addon8@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 8",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// Not hosted, matching override
|
||||
var addon9 = {
|
||||
id: "addon9@tests.mozilla.org",
|
||||
version: "1.0",
|
||||
name: "Test addon 9",
|
||||
targetApplications: [{
|
||||
id: "xpcshell@tests.mozilla.org",
|
||||
minVersion: "1",
|
||||
maxVersion: "1"
|
||||
}]
|
||||
};
|
||||
|
||||
// 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");
|
||||
|
||||
|
||||
/*
|
||||
* Trigger an AddonManager background update check
|
||||
*
|
||||
* @param aCallback
|
||||
* Callback to call once the background update is complete
|
||||
*/
|
||||
function trigger_background_update(aCallback) {
|
||||
Services.obs.addObserver({
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, "addons-background-update-complete");
|
||||
aCallback();
|
||||
}
|
||||
}, "addons-background-update-complete", false);
|
||||
|
||||
gInternalManager.notify(null);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "2");
|
||||
|
||||
writeInstallRDFForExtension(addon1, profileDir);
|
||||
writeInstallRDFForExtension(addon2, profileDir);
|
||||
writeInstallRDFForExtension(addon3, profileDir);
|
||||
writeInstallRDFForExtension(addon4, profileDir);
|
||||
writeInstallRDFForExtension(addon5, profileDir);
|
||||
writeInstallRDFForExtension(addon6, profileDir);
|
||||
writeInstallRDFForExtension(addon7, profileDir);
|
||||
writeInstallRDFForExtension(addon8, profileDir);
|
||||
writeInstallRDFForExtension(addon9, profileDir);
|
||||
writeInstallRDFForExtension(addon10, profileDir);
|
||||
|
||||
gServer = new nsHttpServer();
|
||||
gServer.registerFile(REQ_URL, do_get_file("data/test_compatoverrides.xml"));
|
||||
gServer.start(PORT);
|
||||
|
||||
startupManager();
|
||||
|
||||
trigger_background_update(run_test_1);
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
gServer.stop(do_test_finished);
|
||||
}
|
||||
|
||||
function check_compat_status(aCallback) {
|
||||
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
|
||||
"addon2@tests.mozilla.org",
|
||||
"addon3@tests.mozilla.org",
|
||||
"addon4@tests.mozilla.org",
|
||||
"addon5@tests.mozilla.org",
|
||||
"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]) {
|
||||
|
||||
do_check_neq(a1, null);
|
||||
do_check_eq(a1.compatibilityOverrides, null);
|
||||
do_check_true(a1.isCompatible);
|
||||
do_check_false(a1.appDisabled);
|
||||
|
||||
do_check_neq(a2, null);
|
||||
do_check_eq(a2.compatibilityOverrides, null);
|
||||
do_check_true(a2.isCompatible);
|
||||
do_check_false(a2.appDisabled);
|
||||
|
||||
do_check_neq(a3, null);
|
||||
do_check_neq(a3.compatibilityOverrides, null);
|
||||
do_check_eq(a3.compatibilityOverrides.length, 1);
|
||||
do_check_false(a3.isCompatible);
|
||||
do_check_true(a3.appDisabled);
|
||||
|
||||
do_check_neq(a4, null);
|
||||
do_check_neq(a4.compatibilityOverrides, null);
|
||||
do_check_eq(a4.compatibilityOverrides.length, 1);
|
||||
do_check_false(a4.isCompatible);
|
||||
do_check_true(a4.appDisabled);
|
||||
|
||||
do_check_neq(a5, null);
|
||||
do_check_eq(a5.compatibilityOverrides, null);
|
||||
do_check_true(a5.isCompatible);
|
||||
do_check_false(a5.appDisabled);
|
||||
|
||||
do_check_neq(a6, null);
|
||||
do_check_neq(a6.compatibilityOverrides, null);
|
||||
do_check_eq(a6.compatibilityOverrides.length, 1);
|
||||
do_check_true(a6.isCompatible);
|
||||
do_check_false(a6.appDisabled);
|
||||
|
||||
do_check_neq(a7, null);
|
||||
do_check_neq(a7.compatibilityOverrides, null);
|
||||
do_check_eq(a7.compatibilityOverrides.length, 1);
|
||||
do_check_true(a7.isCompatible);
|
||||
do_check_false(a7.appDisabled);
|
||||
|
||||
do_check_neq(a8, null);
|
||||
do_check_neq(a8.compatibilityOverrides, null);
|
||||
do_check_eq(a8.compatibilityOverrides.length, 3);
|
||||
do_check_false(a8.isCompatible);
|
||||
do_check_true(a8.appDisabled);
|
||||
|
||||
do_check_neq(a9, null);
|
||||
do_check_neq(a9.compatibilityOverrides, null);
|
||||
do_check_eq(a9.compatibilityOverrides.length, 1);
|
||||
do_check_false(a9.isCompatible);
|
||||
do_check_true(a9.appDisabled);
|
||||
|
||||
do_check_neq(a10, null);
|
||||
do_check_eq(a10.compatibilityOverrides, null);
|
||||
do_check_true(a10.isCompatible);
|
||||
do_check_false(a10.appDisabled);
|
||||
|
||||
aCallback();
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_1() {
|
||||
check_compat_status(run_test_2);
|
||||
}
|
||||
|
||||
function run_test_2() {
|
||||
restartManager();
|
||||
check_compat_status(end_test);
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const EXPECTED_SCHEMA_VERSION = 2;
|
||||
const EXPECTED_SCHEMA_VERSION = 3;
|
||||
let dbfile;
|
||||
|
||||
function run_test() {
|
||||
@ -88,6 +88,24 @@ function run_test() {
|
||||
do_check_eq(db.schemaVersion, EXPECTED_SCHEMA_VERSION);
|
||||
do_check_true(db.indexExists("developer_idx"));
|
||||
do_check_true(db.indexExists("screenshot_idx"));
|
||||
do_check_true(db.indexExists("compatibility_override_idx"));
|
||||
do_check_true(db.tableExists("compatibility_override"));
|
||||
|
||||
// Check the trigger is working
|
||||
db.executeSimpleSQL("INSERT INTO addon (id, type, name) VALUES('test_addon', 'extension', 'Test Addon')");
|
||||
let internalID = db.lastInsertRowID;
|
||||
db.executeSimpleSQL("INSERT INTO compatibility_override (addon_internal_id, num, type) VALUES('" + internalID + "', '1', 'incompatible')");
|
||||
|
||||
let stmt = db.createStatement("SELECT COUNT(*) AS count FROM compatibility_override");
|
||||
stmt.executeStep();
|
||||
do_check_eq(stmt.row.count, 1);
|
||||
stmt.reset();
|
||||
|
||||
db.executeSimpleSQL("DELETE FROM addon");
|
||||
stmt.executeStep();
|
||||
do_check_eq(stmt.row.count, 0);
|
||||
stmt.finalize();
|
||||
|
||||
db.close();
|
||||
run_test_2();
|
||||
}
|
||||
|
@ -127,6 +127,7 @@ fail-if = os == "android"
|
||||
[test_cacheflush.js]
|
||||
[test_checkcompatibility.js]
|
||||
[test_ChromeManifestParser.js]
|
||||
[test_compatoverrides.js]
|
||||
[test_corrupt.js]
|
||||
[test_corrupt_strictcompat.js]
|
||||
[test_dictionary.js]
|
||||
|
Loading…
Reference in New Issue
Block a user