зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1592498 - Remove UI migrations up to Firefox 59 and migration 66 for intermittent failures. r=Gijs
Differential Revision: https://phabricator.services.mozilla.com/D96999
This commit is contained in:
Родитель
e0d88600e7
Коммит
9d0b97496e
|
@ -821,7 +821,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||||
LoginBreaches: "resource:///modules/LoginBreaches.jsm",
|
LoginBreaches: "resource:///modules/LoginBreaches.jsm",
|
||||||
NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
|
NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
|
||||||
Normandy: "resource://normandy/Normandy.jsm",
|
Normandy: "resource://normandy/Normandy.jsm",
|
||||||
ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
|
|
||||||
OS: "resource://gre/modules/osfile.jsm",
|
OS: "resource://gre/modules/osfile.jsm",
|
||||||
OsEnvironment: "resource://gre/modules/OsEnvironment.jsm",
|
OsEnvironment: "resource://gre/modules/OsEnvironment.jsm",
|
||||||
PageActions: "resource:///modules/PageActions.jsm",
|
PageActions: "resource:///modules/PageActions.jsm",
|
||||||
|
@ -1134,14 +1133,6 @@ BrowserGlue.prototype = {
|
||||||
if (this._placesBrowserInitComplete) {
|
if (this._placesBrowserInitComplete) {
|
||||||
Services.obs.notifyObservers(null, "places-browser-init-complete");
|
Services.obs.notifyObservers(null, "places-browser-init-complete");
|
||||||
}
|
}
|
||||||
} else if (data == "migrateMatchBucketsPrefForUI66") {
|
|
||||||
this._migrateMatchBucketsPrefForUI66().then(() => {
|
|
||||||
Services.obs.notifyObservers(
|
|
||||||
null,
|
|
||||||
"browser-glue-test",
|
|
||||||
"migrateMatchBucketsPrefForUI66-done"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else if (data == "add-breaches-sync-handler") {
|
} else if (data == "add-breaches-sync-handler") {
|
||||||
this._addBreachesSyncHandler();
|
this._addBreachesSyncHandler();
|
||||||
}
|
}
|
||||||
|
@ -1229,9 +1220,6 @@ BrowserGlue.prototype = {
|
||||||
// Allow certain viewable internally types to be opened from downloads.
|
// Allow certain viewable internally types to be opened from downloads.
|
||||||
DownloadsViewableInternally.register();
|
DownloadsViewableInternally.register();
|
||||||
|
|
||||||
break;
|
|
||||||
case "shield-init-complete":
|
|
||||||
this._shieldInitComplete = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1269,7 +1257,6 @@ BrowserGlue.prototype = {
|
||||||
os.addObserver(this, "xpi-signature-changed");
|
os.addObserver(this, "xpi-signature-changed");
|
||||||
os.addObserver(this, "sync-ui-state:update");
|
os.addObserver(this, "sync-ui-state:update");
|
||||||
os.addObserver(this, "handlersvc-store-initialized");
|
os.addObserver(this, "handlersvc-store-initialized");
|
||||||
os.addObserver(this, "shield-init-complete");
|
|
||||||
|
|
||||||
ActorManagerParent.addJSProcessActors(JSPROCESSACTORS);
|
ActorManagerParent.addJSProcessActors(JSPROCESSACTORS);
|
||||||
ActorManagerParent.addJSWindowActors(JSWINDOWACTORS);
|
ActorManagerParent.addJSWindowActors(JSWINDOWACTORS);
|
||||||
|
@ -1343,7 +1330,6 @@ BrowserGlue.prototype = {
|
||||||
os.removeObserver(this, "flash-plugin-hang");
|
os.removeObserver(this, "flash-plugin-hang");
|
||||||
os.removeObserver(this, "xpi-signature-changed");
|
os.removeObserver(this, "xpi-signature-changed");
|
||||||
os.removeObserver(this, "sync-ui-state:update");
|
os.removeObserver(this, "sync-ui-state:update");
|
||||||
os.removeObserver(this, "shield-init-complete");
|
|
||||||
|
|
||||||
Services.prefs.removeObserver(
|
Services.prefs.removeObserver(
|
||||||
"privacy.trackingprotection",
|
"privacy.trackingprotection",
|
||||||
|
@ -3346,132 +3332,6 @@ BrowserGlue.prototype = {
|
||||||
|
|
||||||
let xulStore = Services.xulStore;
|
let xulStore = Services.xulStore;
|
||||||
|
|
||||||
if (currentUIVersion < 52) {
|
|
||||||
// Keep old devtools log persistence behavior after splitting netmonitor and
|
|
||||||
// webconsole prefs (bug 1307881).
|
|
||||||
if (Services.prefs.getBoolPref("devtools.webconsole.persistlog", false)) {
|
|
||||||
Services.prefs.setBoolPref("devtools.netmonitor.persistlog", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update user customizations that will interfere with the Safe Browsing V2
|
|
||||||
// to V4 migration (bug 1395419).
|
|
||||||
if (currentUIVersion < 53) {
|
|
||||||
const MALWARE_PREF = "urlclassifier.malwareTable";
|
|
||||||
if (Services.prefs.prefHasUserValue(MALWARE_PREF)) {
|
|
||||||
let malwareList = Services.prefs.getCharPref(MALWARE_PREF);
|
|
||||||
if (malwareList.includes("goog-malware-shavar")) {
|
|
||||||
malwareList.replace("goog-malware-shavar", "goog-malware-proto");
|
|
||||||
Services.prefs.setCharPref(MALWARE_PREF, malwareList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentUIVersion < 55) {
|
|
||||||
Services.prefs.clearUserPref("browser.customizemode.tip0.shown");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentUIVersion < 56) {
|
|
||||||
// Prior to the end of the Firefox 57 cycle, the sidebarcommand being present
|
|
||||||
// or not was the only thing that distinguished whether the sidebar was open.
|
|
||||||
// Now, the sidebarcommand always indicates the last opened sidebar, and we
|
|
||||||
// correctly persist the checked attribute to indicate whether or not the
|
|
||||||
// sidebar was open. We should set the checked attribute in case it wasn't:
|
|
||||||
if (xulStore.getValue(BROWSER_DOCURL, "sidebar-box", "sidebarcommand")) {
|
|
||||||
xulStore.setValue(BROWSER_DOCURL, "sidebar-box", "checked", "true");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentUIVersion < 58) {
|
|
||||||
// With Firefox 57, we are doing a one time reset of the geo prefs due to bug 1413652
|
|
||||||
Services.prefs.clearUserPref("browser.search.countryCode");
|
|
||||||
Services.prefs.clearUserPref("browser.search.region");
|
|
||||||
Services.prefs.clearUserPref("browser.search.isUS");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentUIVersion < 59) {
|
|
||||||
let searchInitializedPromise = new Promise(resolve => {
|
|
||||||
if (Services.search.isInitialized) {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
const SEARCH_SERVICE_TOPIC = "browser-search-service";
|
|
||||||
Services.obs.addObserver(function observer(subject, topic, data) {
|
|
||||||
if (data != "init-complete") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Services.obs.removeObserver(observer, SEARCH_SERVICE_TOPIC);
|
|
||||||
resolve();
|
|
||||||
}, SEARCH_SERVICE_TOPIC);
|
|
||||||
});
|
|
||||||
searchInitializedPromise.then(() => {
|
|
||||||
let currentEngine = Services.search.defaultEngine.wrappedJSObject;
|
|
||||||
// Only reset the current engine if it wasn't set by a WebExtension
|
|
||||||
// and it is not one of the default engines.
|
|
||||||
// If the original default is not a default, the user has a weird
|
|
||||||
// configuration probably involving langpacks, it's not worth
|
|
||||||
// attempting to reset their settings.
|
|
||||||
if (
|
|
||||||
currentEngine._extensionID ||
|
|
||||||
currentEngine.isAppProvided ||
|
|
||||||
!Services.search.originalDefaultEngine.isAppProvided
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentEngine._loadPath.startsWith("[https]")) {
|
|
||||||
Services.search.resetToOriginalDefaultEngine();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Migrate the old requested locales prefs to use the new model
|
|
||||||
const SELECTED_LOCALE_PREF = "general.useragent.locale";
|
|
||||||
const MATCHOS_LOCALE_PREF = "intl.locale.matchOS";
|
|
||||||
|
|
||||||
if (
|
|
||||||
Services.prefs.prefHasUserValue(MATCHOS_LOCALE_PREF) ||
|
|
||||||
Services.prefs.prefHasUserValue(SELECTED_LOCALE_PREF)
|
|
||||||
) {
|
|
||||||
if (Services.prefs.getBoolPref(MATCHOS_LOCALE_PREF, false)) {
|
|
||||||
Services.locale.requestedLocales = [];
|
|
||||||
} else {
|
|
||||||
let locale = Services.prefs.getComplexValue(
|
|
||||||
SELECTED_LOCALE_PREF,
|
|
||||||
Ci.nsIPrefLocalizedString
|
|
||||||
);
|
|
||||||
if (locale) {
|
|
||||||
try {
|
|
||||||
Services.locale.requestedLocales = [locale.data];
|
|
||||||
} catch (e) {
|
|
||||||
/* Don't panic if the value is not a valid locale code. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Services.prefs.clearUserPref(SELECTED_LOCALE_PREF);
|
|
||||||
Services.prefs.clearUserPref(MATCHOS_LOCALE_PREF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentUIVersion < 61) {
|
|
||||||
// Remove persisted toolbarset from navigator toolbox
|
|
||||||
xulStore.removeValue(BROWSER_DOCURL, "navigator-toolbox", "toolbarset");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentUIVersion < 62) {
|
|
||||||
// Remove iconsize and mode from all the toolbars
|
|
||||||
let toolbars = [
|
|
||||||
"navigator-toolbox",
|
|
||||||
"nav-bar",
|
|
||||||
"PersonalToolbar",
|
|
||||||
"TabsToolbar",
|
|
||||||
"toolbar-menubar",
|
|
||||||
];
|
|
||||||
for (let resourceName of ["mode", "iconsize"]) {
|
|
||||||
for (let toolbarId of toolbars) {
|
|
||||||
xulStore.removeValue(BROWSER_DOCURL, toolbarId, resourceName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentUIVersion < 64) {
|
if (currentUIVersion < 64) {
|
||||||
OS.File.remove(
|
OS.File.remove(
|
||||||
OS.Path.join(OS.Constants.Path.profileDir, "directoryLinks.json"),
|
OS.Path.join(OS.Constants.Path.profileDir, "directoryLinks.json"),
|
||||||
|
@ -3512,12 +3372,6 @@ BrowserGlue.prototype = {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentUIVersion < 66) {
|
|
||||||
// Set whether search suggestions or history/bookmarks results come first
|
|
||||||
// in the urlbar results, and uninstall a related Shield study.
|
|
||||||
this._migrateMatchBucketsPrefForUI66();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentUIVersion < 67) {
|
if (currentUIVersion < 67) {
|
||||||
// Migrate devtools firebug theme users to light theme (bug 1378108):
|
// Migrate devtools firebug theme users to light theme (bug 1378108):
|
||||||
if (Services.prefs.getCharPref("devtools.theme") == "firebug") {
|
if (Services.prefs.getCharPref("devtools.theme") == "firebug") {
|
||||||
|
@ -4023,93 +3877,6 @@ BrowserGlue.prototype = {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
async _migrateMatchBucketsPrefForUI66() {
|
|
||||||
// This does two related things.
|
|
||||||
//
|
|
||||||
// (1) Profiles created on or after Firefox 57's release date were eligible
|
|
||||||
// for a Shield study that changed the browser.urlbar.matchBuckets pref in
|
|
||||||
// order to show search suggestions above history/bookmarks in the urlbar
|
|
||||||
// popup. This uninstalls that study. (It's actually slightly more
|
|
||||||
// complex. The study set the pref to several possible values, but the
|
|
||||||
// overwhelming number of profiles in the study got search suggestions
|
|
||||||
// first, followed by history/bookmarks.)
|
|
||||||
//
|
|
||||||
// (2) This also ensures that (a) new users see search suggestions above
|
|
||||||
// history/bookmarks, thereby effectively making the study permanent, and
|
|
||||||
// (b) old users (including those in the study) continue to see whatever
|
|
||||||
// they were seeing before. This works together with UnifiedComplete.js.
|
|
||||||
// By default, the browser.urlbar.matchBuckets pref does not exist, and
|
|
||||||
// UnifiedComplete.js internally hardcodes a default value for it. Before
|
|
||||||
// Firefox 60, the hardcoded default was to show history/bookmarks first.
|
|
||||||
// After 60, it's to show search suggestions first.
|
|
||||||
|
|
||||||
// Wait for Shield init to complete.
|
|
||||||
await new Promise(resolve => {
|
|
||||||
if (this._shieldInitComplete) {
|
|
||||||
resolve();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let topic = "shield-init-complete";
|
|
||||||
Services.obs.addObserver(function obs() {
|
|
||||||
Services.obs.removeObserver(obs, topic);
|
|
||||||
resolve();
|
|
||||||
}, topic);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Now get the pref's value. If the study is active, the value will have
|
|
||||||
// just been set (on the default branch) as part of Shield's init. The pref
|
|
||||||
// should not exist otherwise (normally).
|
|
||||||
let prefName = "browser.urlbar.matchBuckets";
|
|
||||||
let prefValue = Services.prefs.getCharPref(prefName, "");
|
|
||||||
|
|
||||||
// Get the study (aka experiment). It may not be installed.
|
|
||||||
let experiment = null;
|
|
||||||
let experimentName = "pref-flip-search-composition-57-release-1413565";
|
|
||||||
let { PreferenceExperiments } = ChromeUtils.import(
|
|
||||||
"resource://normandy/lib/PreferenceExperiments.jsm"
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
experiment = await PreferenceExperiments.get(experimentName);
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
// Uninstall the study, resetting the pref to its state before the study.
|
|
||||||
if (experiment && !experiment.expired) {
|
|
||||||
await PreferenceExperiments.stop(experimentName, {
|
|
||||||
resetValue: true,
|
|
||||||
reason: "external:search-ui-migration",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point, normally the pref should not exist. If it does, then it
|
|
||||||
// either has a user value, or something unexpectedly set its value on the
|
|
||||||
// default branch. Either way, preserve that value.
|
|
||||||
if (Services.prefs.getCharPref(prefName, "")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The new default is "suggestion:4,general:5" (show search suggestions
|
|
||||||
// before history/bookmarks), but we implement that by leaving the pref
|
|
||||||
// undefined, and UnifiedComplete.js hardcodes that value internally. So if
|
|
||||||
// the pref was "suggestion:4,general:5" (modulo whitespace), we're done.
|
|
||||||
if (prefValue) {
|
|
||||||
let buckets = PlacesUtils.convertMatchBucketsStringToArray(prefValue);
|
|
||||||
if (
|
|
||||||
ObjectUtils.deepEqual(buckets, [
|
|
||||||
["suggestion", 4],
|
|
||||||
["general", 5],
|
|
||||||
])
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the pref on the user branch. If the pref had a value, then preserve
|
|
||||||
// it. Otherwise, set the previous default value, which was to show history
|
|
||||||
// and bookmarks before search suggestions.
|
|
||||||
prefValue = prefValue || "general:5,suggestion:Infinity";
|
|
||||||
Services.prefs.setCharPref(prefName, prefValue);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open preferences even if there are no open windows.
|
* Open preferences even if there are no open windows.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,7 +7,3 @@ reason = test depends on update channel
|
||||||
[browser_default_bookmark_toolbar_visibility.js]
|
[browser_default_bookmark_toolbar_visibility.js]
|
||||||
[browser_initial_tab_remoteType.js]
|
[browser_initial_tab_remoteType.js]
|
||||||
[browser_startup_homepage.js]
|
[browser_startup_homepage.js]
|
||||||
[browser_urlbar_matchBuckets_migration60.js]
|
|
||||||
skip-if = os == 'win' #Bug 1592498
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,292 +0,0 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
// Makes sure the browser.urlbar.matchBuckets pref is set correctly starting in
|
|
||||||
// Firefox 60, nsBrowserGlue UI version 66.
|
|
||||||
|
|
||||||
const PREF_NAME = "browser.urlbar.matchBuckets";
|
|
||||||
const PREF_VALUE_SUGGESTIONS_FIRST = "suggestion:4,general:5";
|
|
||||||
const PREF_VALUE_GENERAL_FIRST = "general:5,suggestion:Infinity";
|
|
||||||
const STUDY_NAME = "pref-flip-search-composition-57-release-1413565";
|
|
||||||
|
|
||||||
ChromeUtils.import("resource://normandy/lib/PreferenceExperiments.jsm", this);
|
|
||||||
|
|
||||||
// Migrates without doing anything else. The pref should be set to show history
|
|
||||||
// first.
|
|
||||||
add_task(async function migrate() {
|
|
||||||
await sanityCheckInitialState();
|
|
||||||
|
|
||||||
// Trigger migration. The pref is cleared initially, so after migration it
|
|
||||||
// should be set on the user branch to show history first.
|
|
||||||
await promiseMigration();
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
PREF_VALUE_GENERAL_FIRST,
|
|
||||||
"Pref should be set, general first"
|
|
||||||
);
|
|
||||||
Assert.ok(
|
|
||||||
Services.prefs.prefHasUserValue(PREF_NAME),
|
|
||||||
"Pref should be set on user branch"
|
|
||||||
);
|
|
||||||
|
|
||||||
Services.prefs.clearUserPref(PREF_NAME);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sets the pref to a value on the user branch and migrates. The pref shouldn't
|
|
||||||
// change.
|
|
||||||
add_task(async function setUserPrefAndMigrate() {
|
|
||||||
await sanityCheckInitialState();
|
|
||||||
|
|
||||||
// Set a value for the pref on the user branch.
|
|
||||||
let userValue = "userTest:10";
|
|
||||||
Services.prefs.setCharPref(PREF_NAME, userValue);
|
|
||||||
|
|
||||||
// Trigger migration. The pref should be preserved.
|
|
||||||
await promiseMigration();
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
userValue,
|
|
||||||
"Pref should remain same"
|
|
||||||
);
|
|
||||||
Assert.ok(
|
|
||||||
Services.prefs.prefHasUserValue(PREF_NAME),
|
|
||||||
"Pref should remain on user branch"
|
|
||||||
);
|
|
||||||
|
|
||||||
Services.prefs.clearUserPref(PREF_NAME);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sets the pref to a value on the default branch and migrates. The pref
|
|
||||||
// shouldn't change.
|
|
||||||
add_task(async function setDefaultPrefAndMigrate() {
|
|
||||||
await sanityCheckInitialState();
|
|
||||||
|
|
||||||
// Set a value for the pref on the default branch.
|
|
||||||
let defaultValue = "defaultTest:10";
|
|
||||||
Services.prefs.getDefaultBranch(PREF_NAME).setCharPref("", defaultValue);
|
|
||||||
|
|
||||||
// Trigger migration. The pref should be preserved.
|
|
||||||
await promiseMigration();
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
defaultValue,
|
|
||||||
"Pref should remain same"
|
|
||||||
);
|
|
||||||
Assert.ok(
|
|
||||||
!Services.prefs.prefHasUserValue(PREF_NAME),
|
|
||||||
"Pref should remain on default branch"
|
|
||||||
);
|
|
||||||
|
|
||||||
Services.prefs.deleteBranch(PREF_NAME);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Installs the study using the pref that the overwhelming majority of users
|
|
||||||
// will see ("ratio": 97, "value": "suggestion:4,general:5") and migrates. The
|
|
||||||
// study should be stopped and the pref should remain cleared.
|
|
||||||
add_task(async function installStudyAndMigrate() {
|
|
||||||
await sanityCheckInitialState();
|
|
||||||
|
|
||||||
// Normandy can't unset the pref if it didn't already have a value, so give it
|
|
||||||
// a value that will be treated as empty by the migration.
|
|
||||||
Services.prefs.getDefaultBranch(PREF_NAME).setCharPref("", "");
|
|
||||||
|
|
||||||
// Install the study. It should set the pref.
|
|
||||||
await PreferenceExperiments.start(newExperimentOpts());
|
|
||||||
Assert.ok(await PreferenceExperiments.has(STUDY_NAME), "Study installed");
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
PREF_VALUE_SUGGESTIONS_FIRST,
|
|
||||||
"Pref should be set by study"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Trigger migration. The study should be stopped, and the pref should be
|
|
||||||
// cleared since it's the default value.
|
|
||||||
await promiseMigration();
|
|
||||||
Assert.ok(!(await getNonExpiredExperiment()), "Study stopped");
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
"",
|
|
||||||
"Pref should be cleared"
|
|
||||||
);
|
|
||||||
|
|
||||||
await PreferenceExperiments.clearAllExperimentStorage();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Installs the study using the pref that the overwhelming majority of users
|
|
||||||
// will see ("ratio": 97, "value": "suggestion:4,general:5"), except that the
|
|
||||||
// pref has unnecessary spaces in it, and then migrates. The study should be
|
|
||||||
// stopped and the pref should remain cleared. i.e., the migration code should
|
|
||||||
// parse the pref value and compare the resulting buckets instead of comparing
|
|
||||||
// strings directly.
|
|
||||||
add_task(async function installStudyPrefWithSpacesAndMigrate() {
|
|
||||||
await sanityCheckInitialState();
|
|
||||||
|
|
||||||
// Install the study. It should set the pref.
|
|
||||||
const preferenceValue = " suggestion : 4, general : 5 ";
|
|
||||||
const experiment = newExperimentOpts({
|
|
||||||
preferences: {
|
|
||||||
[PREF_NAME]: {
|
|
||||||
preferenceValue,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await PreferenceExperiments.start(experiment);
|
|
||||||
Assert.ok(await PreferenceExperiments.has(STUDY_NAME), "Study installed");
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
preferenceValue,
|
|
||||||
"Pref should be set by study"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Trigger migration. The study should be stopped, and the pref should be
|
|
||||||
// cleared since it's the default value.
|
|
||||||
await promiseMigration();
|
|
||||||
Assert.ok(!(await getNonExpiredExperiment()), "Study stopped");
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
"",
|
|
||||||
"Pref should be cleared"
|
|
||||||
);
|
|
||||||
|
|
||||||
await PreferenceExperiments.clearAllExperimentStorage();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Installs the study using a pref that a tiny number of users will see
|
|
||||||
// ("ratio": 1, "value": "general:3,suggestion:6") and migrates. The study
|
|
||||||
// should be stopped and the pref should be preserved since it's not the new
|
|
||||||
// default.
|
|
||||||
add_task(async function installStudyMinorityPrefAndMigrate() {
|
|
||||||
await sanityCheckInitialState();
|
|
||||||
|
|
||||||
// Install the study. It should set the pref.
|
|
||||||
let preferenceValue = "general:3,suggestion:6";
|
|
||||||
const experiment = newExperimentOpts({
|
|
||||||
preferences: {
|
|
||||||
[PREF_NAME]: {
|
|
||||||
preferenceValue,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
await PreferenceExperiments.start(experiment);
|
|
||||||
Assert.ok(await PreferenceExperiments.has(STUDY_NAME), "Study installed");
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
preferenceValue,
|
|
||||||
"Pref should be set by study"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Trigger migration. The study should be stopped, and the pref should remain
|
|
||||||
// the same since it's a non-default value. It should be set on the user
|
|
||||||
// branch.
|
|
||||||
await promiseMigration();
|
|
||||||
Assert.ok(!(await getNonExpiredExperiment()), "Study stopped");
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
preferenceValue,
|
|
||||||
"Pref should remain the same"
|
|
||||||
);
|
|
||||||
Assert.ok(
|
|
||||||
Services.prefs.prefHasUserValue(PREF_NAME),
|
|
||||||
"Pref should be set on user branch"
|
|
||||||
);
|
|
||||||
|
|
||||||
await PreferenceExperiments.clearAllExperimentStorage();
|
|
||||||
Services.prefs.clearUserPref(PREF_NAME);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sets the pref to some value on the default branch, installs the study, and
|
|
||||||
// migrates. The study should be stopped and the original pref value should be
|
|
||||||
// restored.
|
|
||||||
add_task(async function setDefaultPrefInstallStudyAndMigrate() {
|
|
||||||
await sanityCheckInitialState();
|
|
||||||
|
|
||||||
// First, set the pref to some value on the default branch. (If the pref is
|
|
||||||
// set on the user branch, starting the study actually throws because the
|
|
||||||
// study's branch is the default branch.)
|
|
||||||
let defaultValue = "test:10";
|
|
||||||
Services.prefs.getDefaultBranch(PREF_NAME).setCharPref("", defaultValue);
|
|
||||||
|
|
||||||
// Install the study. It should set the pref.
|
|
||||||
await PreferenceExperiments.start(newExperimentOpts());
|
|
||||||
Assert.ok(await PreferenceExperiments.has(STUDY_NAME), "Study installed");
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
PREF_VALUE_SUGGESTIONS_FIRST,
|
|
||||||
"Pref should be set by study"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Trigger migration. The study should be stopped, and the pref should be
|
|
||||||
// restored to the value set above.
|
|
||||||
await promiseMigration();
|
|
||||||
Assert.ok(!(await getNonExpiredExperiment()), "Study stopped");
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
defaultValue,
|
|
||||||
"Pref should be restored to user value"
|
|
||||||
);
|
|
||||||
|
|
||||||
await PreferenceExperiments.clearAllExperimentStorage();
|
|
||||||
Services.prefs.deleteBranch(PREF_NAME);
|
|
||||||
});
|
|
||||||
|
|
||||||
async function sanityCheckInitialState() {
|
|
||||||
Assert.equal(
|
|
||||||
Services.prefs.getCharPref(PREF_NAME, ""),
|
|
||||||
"",
|
|
||||||
"Pref should be cleared initially"
|
|
||||||
);
|
|
||||||
Assert.ok(
|
|
||||||
!(await PreferenceExperiments.has(STUDY_NAME)),
|
|
||||||
"Study should not be installed initially"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function promiseMigration() {
|
|
||||||
let topic = "browser-glue-test";
|
|
||||||
let donePromise = TestUtils.topicObserved(topic, (subj, data) => {
|
|
||||||
return "migrateMatchBucketsPrefForUI66-done" == data;
|
|
||||||
});
|
|
||||||
Cc["@mozilla.org/browser/browserglue;1"]
|
|
||||||
.getService(Ci.nsIObserver)
|
|
||||||
.observe(null, topic, "migrateMatchBucketsPrefForUI66");
|
|
||||||
return donePromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
function newExperimentOpts(opts = {}) {
|
|
||||||
const defaultPref = {
|
|
||||||
[PREF_NAME]: {},
|
|
||||||
};
|
|
||||||
const defaultPrefInfo = {
|
|
||||||
preferenceValue: PREF_VALUE_SUGGESTIONS_FIRST,
|
|
||||||
preferenceBranchType: "default",
|
|
||||||
preferenceType: "string",
|
|
||||||
};
|
|
||||||
const preferences = {};
|
|
||||||
for (const [prefName, prefInfo] of Object.entries(
|
|
||||||
opts.preferences || defaultPref
|
|
||||||
)) {
|
|
||||||
preferences[prefName] = { ...defaultPrefInfo, ...prefInfo };
|
|
||||||
}
|
|
||||||
|
|
||||||
return Object.assign(
|
|
||||||
{
|
|
||||||
slug: STUDY_NAME,
|
|
||||||
actionName: "SomeAction",
|
|
||||||
branch: "branch",
|
|
||||||
},
|
|
||||||
opts,
|
|
||||||
{
|
|
||||||
preferences,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getNonExpiredExperiment() {
|
|
||||||
try {
|
|
||||||
let exp = await PreferenceExperiments.get(STUDY_NAME);
|
|
||||||
if (exp.expired) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (ex) {}
|
|
||||||
return null;
|
|
||||||
}
|
|
Загрузка…
Ссылка в новой задаче