Bug 682027 - Add syncGUID field to addons; r=Mossop

This commit is contained in:
Gregory Szorc 2011-11-04 18:04:15 -07:00
parent 55788c9195
commit 2bcb0f0c44
9 changed files with 379 additions and 16 deletions

View File

@ -979,6 +979,37 @@ var AddonManagerInternal = {
});
},
/**
* Asynchronously get an add-on with a specific Sync GUID.
*
* @param aGUID
* String GUID of add-on to retrieve
* @param aCallback
* The callback to pass the retrieved add-on to.
* @throws if the aGUID or aCallback arguments are not specified
*/
getAddonBySyncGUID: function AMI_getAddonBySyncGUID(aGUID, aCallback) {
if (!aGUID || !aCallback) {
throw Cr.NS_ERROR_INVALID_ARG;
}
new AsyncObjectCaller(this.providers, "getAddonBySyncGUID", {
nextObject: function(aCaller, aProvider) {
callProvider(aProvider, "getAddonBySyncGUID", null, aGUID, function(aAddon) {
if (aAddon) {
safeCall(aCallback, aAddon);
} else {
aCaller.callNext();
}
});
},
noMoreObjects: function(aCaller) {
safeCall(aCallback, null);
}
});
},
/**
* Asynchronously gets an array of add-ons.
*
@ -1377,6 +1408,10 @@ var AddonManager = {
AddonManagerInternal.getAddonByID(aId, aCallback);
},
getAddonBySyncGUID: function AM_getAddonBySyncGUID(aId, aCallback) {
AddonManagerInternal.getAddonBySyncGUID(aId, aCallback);
},
getAddonsByIDs: function AM_getAddonsByIDs(aIds, aCallback) {
AddonManagerInternal.getAddonsByIDs(aIds, aCallback);
},

View File

@ -127,7 +127,7 @@ const TOOLKIT_ID = "toolkit@mozilla.org";
const BRANCH_REGEXP = /^([^\.]+\.[0-9]+[a-z]*).*/gi;
const DB_SCHEMA = 8;
const DB_SCHEMA = 9;
const REQ_VERSION = 2;
#ifdef MOZ_COMPATIBILITY_NIGHTLY
@ -147,8 +147,13 @@ const PROP_LOCALE_MULTI = ["developers", "translators", "contributors"];
const PROP_TARGETAPP = ["id", "minVersion", "maxVersion"];
// Properties that only exist in the database
const DB_METADATA = ["installDate", "updateDate", "size", "sourceURI",
"releaseNotesURI", "applyBackgroundUpdates"];
const DB_METADATA = ["syncGUID",
"installDate",
"updateDate",
"size",
"sourceURI",
"releaseNotesURI",
"applyBackgroundUpdates"];
const DB_BOOL_METADATA = ["visible", "active", "userDisabled", "appDisabled",
"pendingUninstall", "bootstrap", "skinnable",
"softDisabled", "foreignInstall",
@ -2471,6 +2476,7 @@ var XPIProvider = {
// the applyBlocklistChanges code
let newAddon = new AddonInternal();
newAddon.id = aOldAddon.id;
newAddon.syncGUID = aOldAddon.syncGUID;
newAddon.version = aOldAddon.version;
newAddon.type = aOldAddon.type;
newAddon.appDisabled = !isUsableAddon(aOldAddon);
@ -2641,6 +2647,8 @@ var XPIProvider = {
// preference which is read in loadManifestFromRDF
if (newAddon.type != "theme")
newAddon.userDisabled = aMigrateData.userDisabled;
if ("syncGUID" in aMigrateData)
newAddon.syncGUID = aMigrateData.syncGUID;
if ("installDate" in aMigrateData)
newAddon.installDate = aMigrateData.installDate;
if ("softDisabled" in aMigrateData)
@ -3190,6 +3198,23 @@ var XPIProvider = {
});
},
/**
* Obtain an Addon having the specified Sync GUID.
*
* @param aGUID
* String GUID of add-on to retrieve
* @param aCallback
* A callback to pass the Addon to. Receives null if not found.
*/
getAddonBySyncGUID: function XPI_getAddonBySyncGUID(aGUID, aCallback) {
XPIDatabase.getAddonBySyncGUID(aGUID, function(aAddon) {
if (aAddon)
aCallback(createWrapper(aAddon));
else
aCallback(null);
});
},
/**
* Called to get Addons that have pending operations.
*
@ -3917,10 +3942,11 @@ var XPIProvider = {
}
};
const FIELDS_ADDON = "internal_id, id, location, version, type, internalName, " +
"updateURL, updateKey, optionsURL, optionsType, aboutURL, " +
"iconURL, icon64URL, defaultLocale, visible, active, " +
"userDisabled, appDisabled, pendingUninstall, descriptor, " +
const FIELDS_ADDON = "internal_id, id, syncGUID, location, version, type, " +
"internalName, updateURL, updateKey, optionsURL, " +
"optionsType, aboutURL, iconURL, icon64URL, " +
"defaultLocale, visible, active, userDisabled, " +
"appDisabled, pendingUninstall, descriptor, " +
"installDate, updateDate, applyBackgroundUpdates, bootstrap, " +
"skinnable, size, sourceURI, releaseNotesURI, softDisabled, " +
"foreignInstall, hasBinaryComponents, strictCompatibility";
@ -4063,9 +4089,10 @@ var XPIDatabase = {
_readLocaleStrings: "SELECT locale_id, type, value FROM locale_strings " +
"WHERE locale_id=:id",
addAddonMetadata_addon: "INSERT INTO addon VALUES (NULL, :id, :location, " +
":version, :type, :internalName, :updateURL, " +
":updateKey, :optionsURL, :optionsType, :aboutURL, " +
addAddonMetadata_addon: "INSERT INTO addon VALUES (NULL, :id, :syncGUID, " +
":location, :version, :type, :internalName, " +
":updateURL, :updateKey, :optionsURL, " +
":optionsType, :aboutURL, " +
":iconURL, :icon64URL, :locale, :visible, :active, " +
":userDisabled, :appDisabled, :pendingUninstall, " +
":descriptor, :installDate, :updateDate, " +
@ -4112,7 +4139,8 @@ var XPIDatabase = {
"addon WHERE visible=1 " +
"AND (pendingUninstall=1 OR " +
"MAX(userDisabled,appDisabled)=active)",
getAddonBySyncGUID: "SELECT " + FIELDS_ADDON + " FROM addon " +
"WHERE syncGUID=:syncGUID",
makeAddonVisible: "UPDATE addon SET visible=1 WHERE internal_id=:internal_id",
removeAddonMetadata: "DELETE FROM addon WHERE internal_id=:internal_id",
// Equates to active = visible && !userDisabled && !softDisabled &&
@ -4127,6 +4155,8 @@ var XPIDatabase = {
"internal_id=:internal_id",
setAddonDescriptor: "UPDATE addon SET descriptor=:descriptor WHERE " +
"internal_id=:internal_id",
setAddonSyncGUID: "UPDATE addon SET syncGUID=:syncGUID WHERE " +
"internal_id=:internal_id",
updateTargetApplications: "UPDATE targetApplication SET " +
"minVersion=:minVersion, maxVersion=:maxVersion " +
"WHERE addon_internal_id=:internal_id AND id=:id",
@ -4449,6 +4479,9 @@ var XPIDatabase = {
// Build a list of sql statements that might recover useful data from this
// and future versions of the schema
var sql = [];
sql.push("SELECT internal_id, id, syncGUID, location, userDisabled, " +
"softDisabled, installDate, version, applyBackgroundUpdates, " +
"sourceURI, releaseNotesURI, foreignInstall FROM addon");
sql.push("SELECT internal_id, id, location, userDisabled, " +
"softDisabled, installDate, version, applyBackgroundUpdates, " +
"sourceURI, releaseNotesURI, foreignInstall FROM addon");
@ -4486,6 +4519,8 @@ var XPIDatabase = {
targetApplications: []
};
if ("syncGUID" in row)
migrateData[row.location][row.id].syncGUID = row.syncGUID;
if ("softDisabled" in row)
migrateData[row.location][row.id].softDisabled = row.softDisabled == 1;
if ("applyBackgroundUpdates" in row)
@ -4603,7 +4638,8 @@ var XPIDatabase = {
try {
this.connection.createTable("addon",
"internal_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"id TEXT, location TEXT, version TEXT, " +
"id TEXT, syncGUID TEXT, " +
"location TEXT, version TEXT, " +
"type TEXT, internalName TEXT, updateURL TEXT, " +
"updateKey TEXT, optionsURL TEXT, " +
"optionsType TEXT, aboutURL TEXT, iconURL TEXT, " +
@ -4619,7 +4655,8 @@ var XPIDatabase = {
"foreignInstall INTEGER, " +
"hasBinaryComponents INTEGER, " +
"strictCompatibility INTEGER, " +
"UNIQUE (id, location)");
"UNIQUE (id, location), " +
"UNIQUE (syncGUID)");
this.connection.createTable("targetApplication",
"addon_internal_id INTEGER, " +
"id TEXT, minVersion TEXT, maxVersion TEXT, " +
@ -5203,6 +5240,29 @@ var XPIDatabase = {
stmt.executeAsync(new AsyncAddonListCallback(aCallback));
},
/**
* Asynchronously get an add-on by its Sync GUID.
*
* @param aGUID
* Sync GUID of add-on to fetch
* @param aCallback
* A callback to pass the DBAddonInternal record to. Receives null
* if no add-on with that GUID is found.
*
*/
getAddonBySyncGUID: function XPIDB_getAddonBySyncGUID(aGUID, aCallback) {
let stmt = this.getStatement("getAddonBySyncGUID");
stmt.params.syncGUID = aGUID;
stmt.executeAsync(new AsyncAddonListCallback(function(aAddons) {
if (aAddons.length == 0) {
aCallback(null);
return;
}
aCallback(aAddons[0]);
}));
},
/**
* Synchronously gets all add-ons in the database.
*
@ -5226,6 +5286,18 @@ var XPIDatabase = {
* The file descriptor of the add-on
*/
addAddonMetadata: function XPIDB_addAddonMetadata(aAddon, aDescriptor) {
// Create a GUID if one does not exist
if (!aAddon.syncGUID) {
let rng = Cc["@mozilla.org/security/random-generator;1"].
createInstance(Ci.nsIRandomGenerator);
let bytes = rng.generateRandomBytes(9);
let byte_string = [String.fromCharCode(byte) for each (byte in bytes)]
.join("");
// Base64 encode
aAddon.syncGUID = btoa(byte_string).replace('+', '-', 'g')
.replace('/', '_', 'g');
}
// If there is no DB yet then forcibly create one
if (!this.connection)
this.openConnection(false, true);
@ -5330,11 +5402,13 @@ var XPIDatabase = {
// Any errors in here should rollback the transaction
try {
this.removeAddonMetadata(aOldAddon);
aNewAddon.syncGUID = aOldAddon.syncGUID;
aNewAddon.installDate = aOldAddon.installDate;
aNewAddon.applyBackgroundUpdates = aOldAddon.applyBackgroundUpdates;
aNewAddon.foreignInstall = aOldAddon.foreignInstall;
aNewAddon.active = (aNewAddon.visible && !aNewAddon.userDisabled &&
!aNewAddon.appDisabled)
this.addAddonMetadata(aNewAddon, aDescriptor);
this.commitTransaction();
}
@ -5445,6 +5519,22 @@ var XPIDatabase = {
executeStatement(stmt);
},
/**
* Synchronously sets the Sync GUID for an add-on.
*
* @param aAddon
* The DBAddonInternal being updated
* @param aGUID
* GUID string to set the value to
*/
setAddonSyncGUID: function XPIDB_setAddonSyncGUID(aAddon, aGUID) {
let stmt = this.getStatement("setAddonSyncGUID");
stmt.params.internal_id = aAddon._internal_id;
stmt.params.syncGUID = aGUID;
executeStatement(stmt);
},
/**
* Synchronously sets the file descriptor for an add-on.
*
@ -7267,7 +7357,7 @@ function AddonWrapper(aAddon) {
return [objValue, false];
}
["id", "version", "type", "isCompatible", "isPlatformCompatible",
["id", "syncGUID", "version", "type", "isCompatible", "isPlatformCompatible",
"providesUpdatesSecurely", "blocklistState", "blocklistURL", "appDisabled",
"softDisabled", "skinnable", "size", "foreignInstall", "hasBinaryComponents",
"strictCompatibility"].forEach(function(aProp) {
@ -7449,6 +7539,16 @@ function AddonWrapper(aAddon) {
return val;
});
this.__defineSetter__("syncGUID", function(val) {
if (aAddon.syncGUID == val)
return val;
XPIDatabase.setAddonSyncGUID(aAddon, val);
aAddon.syncGUID = val;
return val;
});
this.__defineGetter__("install", function() {
if (!("_install" in aAddon) || !aAddon._install)
return null;

View File

@ -72,6 +72,7 @@ function run_test_1() {
do_check_eq(install.name, "Test 1");
do_check_eq(install.state, AddonManager.STATE_DOWNLOADED);
do_check_true(install.addon.hasResource("install.rdf"));
do_check_eq(install.addon.syncGUID, null);
do_check_eq(install.addon.install, install);
do_check_eq(install.addon.size, ADDON1_SIZE);
do_check_true(hasFlag(install.addon.operationsRequiringRestart,
@ -157,6 +158,8 @@ function check_test_1() {
AddonManager.getAddonByID("addon1@tests.mozilla.org", function(a1) {
do_check_neq(a1, null);
do_check_neq(a1.syncGUID, null);
do_check_true(a1.syncGUID.length >= 9);
do_check_eq(a1.type, "extension");
do_check_eq(a1.version, "1.0");
do_check_eq(a1.name, "Test 1");
@ -274,6 +277,7 @@ function check_test_3(aInstall) {
AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
do_check_neq(a2, null);
do_check_neq(a2.syncGUID, null);
do_check_eq(a2.type, "extension");
do_check_eq(a2.version, "2.0");
do_check_eq(a2.name, "Real Test 2");
@ -462,6 +466,7 @@ function check_test_7() {
AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
do_check_neq(a3, null);
do_check_neq(a3.syncGUID, null);
do_check_eq(a3.type, "extension");
do_check_eq(a3.version, "1.0");
do_check_eq(a3.name, "Real Test 4");
@ -506,6 +511,7 @@ function check_test_8() {
AddonManager.getAddonByID("addon3@tests.mozilla.org", function(a3) {
do_check_neq(a3, null);
do_check_neq(a3.syncGUID, null);
do_check_eq(a3.type, "extension");
do_check_eq(a3.version, "1.0");
do_check_eq(a3.name, "Real Test 4");

View File

@ -82,6 +82,8 @@ profileDir.append("extensions");
do_load_httpd_js();
var testserver;
let oldSyncGUIDs = {};
function prepare_profile() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
@ -114,7 +116,11 @@ function prepare_profile() {
a2.applyBackgroundUpdates = false;
a4.userDisabled = true;
a6.userDisabled = true;
for each (let addon in [a1, a2, a3, a4, a5, a6]) {
oldSyncGUIDs[addon.id] = addon.syncGUID;
}
a6.findUpdates({
onUpdateAvailable: function(aAddon, aInstall6) {
AddonManager.getInstallForURL("http://localhost:4444/addons/test_migrate4_7.xpi", function(aInstall7) {
@ -180,6 +186,7 @@ function test_results() {
function([a1, a2, a3, a4, a5, a6, a7, a8]) {
// addon1 was enabled
do_check_neq(a1, null);
do_check_eq(a1.syncGUID, oldSyncGUIDs[a1.id]);
do_check_false(a1.userDisabled);
do_check_false(a1.appDisabled);
do_check_true(a1.isActive);
@ -190,6 +197,7 @@ function test_results() {
// addon2 was disabled
do_check_neq(a2, null);
do_check_eq(a2.syncGUID, oldSyncGUIDs[a2.id]);
do_check_true(a2.userDisabled);
do_check_false(a2.appDisabled);
do_check_false(a2.isActive);
@ -200,6 +208,7 @@ function test_results() {
// addon3 was pending-disable in the database
do_check_neq(a3, null);
do_check_eq(a3.syncGUID, oldSyncGUIDs[a3.id]);
do_check_true(a3.userDisabled);
do_check_false(a3.appDisabled);
do_check_false(a3.isActive);
@ -210,6 +219,7 @@ function test_results() {
// addon4 was pending-enable in the database
do_check_neq(a4, null);
do_check_eq(a4.syncGUID, oldSyncGUIDs[a4.id]);
do_check_false(a4.userDisabled);
do_check_false(a4.appDisabled);
do_check_true(a4.isActive);
@ -230,6 +240,7 @@ function test_results() {
// addon6 was disabled and compatible but a new version has been installed
do_check_neq(a6, null);
do_check_eq(a6.syncGUID, oldSyncGUIDs[a6.id]);
do_check_eq(a6.version, "2.0");
do_check_true(a6.userDisabled);
do_check_false(a6.appDisabled);

View File

@ -208,6 +208,8 @@ function run_test_1() {
do_check_neq(a1, null);
do_check_eq(a1.id, "addon1@tests.mozilla.org");
do_check_neq(a1.syncGUID, null);
do_check_true(a1.syncGUID.length >= 9);
do_check_eq(a1.version, "1.0");
do_check_eq(a1.name, "Test 1");
do_check_true(isExtensionInAddonsList(profileDir, a1.id));
@ -220,6 +222,8 @@ function run_test_1() {
do_check_neq(a2, null);
do_check_eq(a2.id, "addon2@tests.mozilla.org");
do_check_neq(a2.syncGUID, null);
do_check_true(a2.syncGUID.length >= 9);
do_check_eq(a2.version, "2.0");
do_check_eq(a2.name, "Test 2");
do_check_true(isExtensionInAddonsList(profileDir, a2.id));
@ -232,6 +236,8 @@ function run_test_1() {
do_check_neq(a3, null);
do_check_eq(a3.id, "addon3@tests.mozilla.org");
do_check_neq(a3.syncGUID, null);
do_check_true(a3.syncGUID.length >= 9);
do_check_eq(a3.version, "3.0");
do_check_eq(a3.name, "Test 3");
do_check_true(isExtensionInAddonsList(profileDir, a3.id));

View File

@ -0,0 +1,151 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
Components.utils.import("resource://gre/modules/Services.jsm");
// restartManager() mucks with XPIProvider.jsm importing, so we hack around.
this.__defineGetter__("XPIProvider", function () {
let scope = {};
return Components.utils.import("resource://gre/modules/XPIProvider.jsm", scope)
.XPIProvider;
});
const addonId = "addon1@tests.mozilla.org";
function run_test() {
Services.prefs.setBoolPref("extensions.checkUpdateSecurity", false);
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9");
startupManager();
run_next_test();
}
add_test(function test_getter_and_setter() {
// Our test add-on requires a restart.
let listener = {
onInstallEnded: function onInstallEnded() {
restartManager();
AddonManager.getAddonByID(addonId, function(addon) {
do_check_neq(addon, null);
do_check_neq(addon.syncGUID, null);
do_check_true(addon.syncGUID.length >= 9);
let oldGUID = addon.SyncGUID;
let newGUID = "foo";
addon.syncGUID = newGUID;
do_check_eq(newGUID, addon.syncGUID);
// Verify change made it to DB.
AddonManager.getAddonByID(addonId, function(newAddon) {
do_check_neq(newAddon, null);
do_check_eq(newGUID, newAddon.syncGUID);
});
AddonManager.removeInstallListener(listener);
run_next_test();
});
}
};
AddonManager.addInstallListener(listener);
AddonManager.getInstallForFile(do_get_addon("test_install1"),
function(install) {
install.install();
});
});
add_test(function test_fetch_by_guid_unknown_guid() {
XPIProvider.getAddonBySyncGUID("XXXX", function(addon) {
do_check_eq(null, addon);
run_next_test();
});
});
// Ensure setting an extension to an existing syncGUID results in error.
add_test(function test_error_on_duplicate_syncguid_insert() {
const installNames = ["test_install1", "test_install2_1"];
const installIDs = ["addon1@tests.mozilla.org", "addon2@tests.mozilla.org"];
let installCount = 0;
let listener = {
onInstallEnded: function onInstallEnded() {
installCount++;
if (installCount == installNames.length) {
AddonManager.removeInstallListener(listener);
restartManager();
AddonManager.getAddonsByIDs(installIDs, function(addons) {
let initialGUID = addons[1].syncGUID;
try {
addons[1].syncGUID = addons[0].syncGUID;
do_throw("Should not get here.");
}
catch (e) {
do_check_eq(e.result,
Components.results.NS_ERROR_STORAGE_CONSTRAINT);
restartManager();
AddonManager.getAddonByID(installIDs[1], function(addon) {
do_check_eq(initialGUID, addon.syncGUID);
run_next_test();
});
}
});
}
}
};
AddonManager.addInstallListener(listener);
let getInstallCB = function(install) { install.install(); };
for each (let name in installNames) {
AddonManager.getInstallForFile(do_get_addon(name), getInstallCB);
}
});
add_test(function test_fetch_by_guid_known_guid() {
AddonManager.getAddonByID(addonId, function(addon) {
do_check_neq(null, addon);
do_check_neq(null, addon.syncGUID);
let syncGUID = addon.syncGUID;
XPIProvider.getAddonBySyncGUID(syncGUID, function(newAddon) {
do_check_neq(null, newAddon);
do_check_eq(syncGUID, newAddon.syncGUID);
run_next_test();
});
});
});
add_test(function test_addon_manager_get_by_sync_guid() {
AddonManager.getAddonByID(addonId, function(addon) {
do_check_neq(null, addon.syncGUID);
let syncGUID = addon.syncGUID;
AddonManager.getAddonBySyncGUID(syncGUID, function(newAddon) {
do_check_neq(null, newAddon);
do_check_eq(addon.id, newAddon.id);
do_check_eq(syncGUID, newAddon.syncGUID);
AddonManager.getAddonBySyncGUID("DOES_NOT_EXIST", function(missing) {
do_check_eq(undefined, missing);
run_next_test();
});
});
});
});

View File

@ -27,6 +27,8 @@ var testserver;
const profileDir = gProfD.clone();
profileDir.append("extensions");
let originalSyncGUID;
function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9.2");
Services.prefs.setBoolPref(PREF_MATCH_OS_LOCALE, false);
@ -92,7 +94,9 @@ function run_test_1() {
do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DEFAULT);
do_check_eq(a1.releaseNotesURI, null);
do_check_true(a1.foreignInstall);
do_check_neq(a1.syncGUID, null);
originalSyncGUID = a1.syncGUID;
a1.applyBackgroundUpdates = AddonManager.AUTOUPDATE_DEFAULT;
prepare_test({
@ -222,6 +226,8 @@ function check_test_2() {
do_check_eq(a1.applyBackgroundUpdates, AddonManager.AUTOUPDATE_DISABLE);
do_check_eq(a1.releaseNotesURI.spec, "http://example.com/updateInfo.xhtml");
do_check_true(a1.foreignInstall);
do_check_neq(a1.syncGUID, null);
do_check_eq(originalSyncGUID, a1.syncGUID);
a1.uninstall();
restartManager();
@ -1016,6 +1022,45 @@ function check_test_15(aInstall) {
restartManager();
end_test();
run_test_16();
});
}
function run_test_16() {
restartManager();
let url = "http://localhost:4444/addons/test_install2_1.xpi";
AddonManager.getInstallForURL(url, function(aInstall) {
aInstall.addListener({
onInstallEnded: function() {
restartManager();
AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a1) {
do_check_neq(a1.syncGUID, null);
let oldGUID = a1.syncGUID;
let url = "http://localhost:4444/addons/test_install2_2.xpi";
AddonManager.getInstallForURL(url, function(aInstall) {
aInstall.addListener({
onInstallEnded: function() {
restartManager();
AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
do_check_neq(a2.syncGUID, null);
do_check_eq(oldGUID, a2.syncGUID);
a2.uninstall();
restartManager();
end_test();
});
}
});
aInstall.install();
}, "application/x-xpinstall");
});
}
});
aInstall.install();
}, "application/x-xpinstall");
}

View File

@ -95,6 +95,9 @@ function check_test_1(install) {
do_check_neq(a1.pendingUpgrade, null);
do_check_eq(a1.pendingUpgrade.id, "addon2@tests.mozilla.org");
do_check_eq(a1.pendingUpgrade.install.existingAddon, a1);
do_check_neq(a1.syncGUID);
let a1SyncGUID = a1.syncGUID;
restartManager();
@ -103,6 +106,10 @@ function check_test_1(install) {
// Should have uninstalled the old and installed the new
do_check_eq(a1, null);
do_check_neq(a2, null);
do_check_neq(a2.syncGUID, null);
// The Sync GUID should change when the ID changes
do_check_neq(a1SyncGUID, a2.syncGUID);
a2.uninstall();
@ -283,6 +290,7 @@ function run_test_4() {
AddonManager.getAddonByID("addon2@tests.mozilla.org", function(a2) {
do_check_neq(a2, null);
do_check_neq(a2.syncGUID, null);
do_check_eq(a2.version, "2.0");
a2.findUpdates({

View File

@ -183,6 +183,7 @@ fail-if = os == "android"
[test_startup.js]
# Bug 676992: test consistently fails on Android
fail-if = os == "android"
[test_syncGUID.js]
[test_strictcompatibility.js]
[test_targetPlatforms.js]
[test_theme.js]