forked from mirrors/gecko-dev
MozReview-Commit-ID: 3kHo7b69vdS --HG-- extra : rebase_source : 58700651c8b1e8342df765cd6aa8a7e770d47b42
302 lines
11 KiB
JavaScript
302 lines
11 KiB
JavaScript
"use strict";
|
|
|
|
ChromeUtils.import("resource://normandy/Normandy.jsm", this);
|
|
ChromeUtils.import("resource://normandy/lib/AddonStudies.jsm", this);
|
|
ChromeUtils.import("resource://normandy/lib/PreferenceExperiments.jsm", this);
|
|
ChromeUtils.import("resource://normandy/lib/PreferenceRollouts.jsm", this);
|
|
ChromeUtils.import("resource://normandy/lib/RecipeRunner.jsm", this);
|
|
ChromeUtils.import("resource://normandy/lib/TelemetryEvents.jsm", this);
|
|
ChromeUtils.import("resource://normandy-content/AboutPages.jsm", this);
|
|
|
|
const experimentPref1 = "test.initExperimentPrefs1";
|
|
const experimentPref2 = "test.initExperimentPrefs2";
|
|
const experimentPref3 = "test.initExperimentPrefs3";
|
|
const experimentPref4 = "test.initExperimentPrefs4";
|
|
|
|
function withStubInits(testFunction) {
|
|
return decorate(
|
|
withStub(AboutPages, "init"),
|
|
withStub(AddonStudies, "init"),
|
|
withStub(PreferenceRollouts, "init"),
|
|
withStub(PreferenceExperiments, "init"),
|
|
withStub(RecipeRunner, "init"),
|
|
withStub(TelemetryEvents, "init"),
|
|
() => testFunction(),
|
|
);
|
|
}
|
|
|
|
decorate_task(
|
|
withPrefEnv({
|
|
set: [
|
|
[`app.normandy.startupExperimentPrefs.${experimentPref1}`, true],
|
|
[`app.normandy.startupExperimentPrefs.${experimentPref2}`, 2],
|
|
[`app.normandy.startupExperimentPrefs.${experimentPref3}`, "string"],
|
|
],
|
|
}),
|
|
async function testApplyStartupPrefs() {
|
|
const defaultBranch = Services.prefs.getDefaultBranch("");
|
|
for (const pref of [experimentPref1, experimentPref2, experimentPref3]) {
|
|
is(
|
|
defaultBranch.getPrefType(pref),
|
|
defaultBranch.PREF_INVALID,
|
|
`Pref ${pref} don't exist before being initialized.`,
|
|
);
|
|
}
|
|
|
|
let oldValues = Normandy.applyStartupPrefs("app.normandy.startupExperimentPrefs.");
|
|
|
|
Assert.deepEqual(oldValues, {
|
|
[experimentPref1]: null,
|
|
[experimentPref2]: null,
|
|
[experimentPref3]: null,
|
|
}, "the correct set of old values should be reported");
|
|
|
|
ok(
|
|
defaultBranch.getBoolPref(experimentPref1),
|
|
`Pref ${experimentPref1} has a default value after being initialized.`,
|
|
);
|
|
is(
|
|
defaultBranch.getIntPref(experimentPref2),
|
|
2,
|
|
`Pref ${experimentPref2} has a default value after being initialized.`,
|
|
);
|
|
is(
|
|
defaultBranch.getCharPref(experimentPref3),
|
|
"string",
|
|
`Pref ${experimentPref3} has a default value after being initialized.`,
|
|
);
|
|
|
|
for (const pref of [experimentPref1, experimentPref2, experimentPref3]) {
|
|
ok(
|
|
!defaultBranch.prefHasUserValue(pref),
|
|
`Pref ${pref} doesn't have a user value after being initialized.`,
|
|
);
|
|
Services.prefs.clearUserPref(pref);
|
|
defaultBranch.deleteBranch(pref);
|
|
}
|
|
},
|
|
);
|
|
|
|
decorate_task(
|
|
withPrefEnv({
|
|
set: [
|
|
["app.normandy.startupExperimentPrefs.test.existingPref", "experiment"],
|
|
],
|
|
}),
|
|
async function testApplyStartupPrefsExisting() {
|
|
const defaultBranch = Services.prefs.getDefaultBranch("");
|
|
defaultBranch.setCharPref("test.existingPref", "default");
|
|
Normandy.applyStartupPrefs("app.normandy.startupExperimentPrefs.");
|
|
is(
|
|
defaultBranch.getCharPref("test.existingPref"),
|
|
"experiment",
|
|
"applyStartupPrefs overwrites the default values of existing preferences.",
|
|
);
|
|
},
|
|
);
|
|
|
|
decorate_task(
|
|
withPrefEnv({
|
|
set: [
|
|
["app.normandy.startupExperimentPrefs.test.mismatchPref", "experiment"],
|
|
],
|
|
}),
|
|
async function testApplyStartupPrefsMismatch() {
|
|
const defaultBranch = Services.prefs.getDefaultBranch("");
|
|
defaultBranch.setIntPref("test.mismatchPref", 2);
|
|
Normandy.applyStartupPrefs("app.normandy.startupExperimentPrefs.");
|
|
is(
|
|
defaultBranch.getPrefType("test.mismatchPref"),
|
|
Services.prefs.PREF_INT,
|
|
"applyStartupPrefs skips prefs that don't match the existing default value's type.",
|
|
);
|
|
},
|
|
);
|
|
|
|
decorate_task(
|
|
withStub(Normandy, "finishInit"),
|
|
async function testStartupDelayed(finishInitStub) {
|
|
Normandy.init();
|
|
ok(
|
|
!finishInitStub.called,
|
|
"When initialized, do not call finishInit immediately.",
|
|
);
|
|
|
|
Normandy.observe(null, "sessionstore-windows-restored");
|
|
ok(
|
|
finishInitStub.called,
|
|
"Once the sessionstore-windows-restored event is observed, finishInit should be called.",
|
|
);
|
|
},
|
|
);
|
|
|
|
// During startup, preferences that are changed for experiments should
|
|
// be record by calling PreferenceExperiments.recordOriginalValues.
|
|
decorate_task(
|
|
withStub(PreferenceExperiments, "recordOriginalValues"),
|
|
withStub(PreferenceRollouts, "recordOriginalValues"),
|
|
async function testApplyStartupPrefs(experimentsRecordOriginalValuesStub, rolloutsRecordOriginalValueStub) {
|
|
const defaultBranch = Services.prefs.getDefaultBranch("");
|
|
|
|
defaultBranch.setBoolPref(experimentPref1, false);
|
|
defaultBranch.setIntPref(experimentPref2, 1);
|
|
defaultBranch.setCharPref(experimentPref3, "original string");
|
|
// experimentPref4 is left unset
|
|
|
|
Normandy.applyStartupPrefs("app.normandy.startupExperimentPrefs.");
|
|
Normandy.studyPrefsChanged = {"test.study-pref": 1};
|
|
Normandy.rolloutPrefsChanged = {"test.rollout-pref": 1};
|
|
await Normandy.finishInit();
|
|
|
|
Assert.deepEqual(
|
|
experimentsRecordOriginalValuesStub.args,
|
|
[[{"test.study-pref": 1}]],
|
|
"finishInit should record original values of the study prefs",
|
|
);
|
|
Assert.deepEqual(
|
|
rolloutsRecordOriginalValueStub.args,
|
|
[[{"test.rollout-pref": 1}]],
|
|
"finishInit should record original values of the study prefs",
|
|
);
|
|
|
|
// cleanup
|
|
defaultBranch.deleteBranch(experimentPref1);
|
|
defaultBranch.deleteBranch(experimentPref2);
|
|
defaultBranch.deleteBranch(experimentPref3);
|
|
},
|
|
);
|
|
|
|
// Test that startup prefs are handled correctly when there is a value on the user branch but not the default branch.
|
|
decorate_task(
|
|
withPrefEnv({
|
|
set: [
|
|
["app.normandy.startupExperimentPrefs.testing.does-not-exist", "foo"],
|
|
["testing.does-not-exist", "foo"],
|
|
],
|
|
}),
|
|
withStub(PreferenceExperiments, "recordOriginalValues"),
|
|
async function testApplyStartupPrefsNoDefaultValue() {
|
|
Normandy.applyStartupPrefs("app.normandy.startupExperimentPrefs");
|
|
ok(true, "initExperimentPrefs should not throw for prefs that doesn't exist on the default branch");
|
|
},
|
|
);
|
|
|
|
decorate_task(
|
|
withStubInits,
|
|
async function testStartup() {
|
|
const initObserved = TestUtils.topicObserved("shield-init-complete");
|
|
await Normandy.finishInit();
|
|
ok(AboutPages.init.called, "startup calls AboutPages.init");
|
|
ok(AddonStudies.init.called, "startup calls AddonStudies.init");
|
|
ok(PreferenceExperiments.init.called, "startup calls PreferenceExperiments.init");
|
|
ok(RecipeRunner.init.called, "startup calls RecipeRunner.init");
|
|
await initObserved;
|
|
}
|
|
);
|
|
|
|
decorate_task(
|
|
withStubInits,
|
|
async function testStartupPrefInitFail() {
|
|
PreferenceExperiments.init.rejects();
|
|
|
|
await Normandy.finishInit();
|
|
ok(AboutPages.init.called, "startup calls AboutPages.init");
|
|
ok(AddonStudies.init.called, "startup calls AddonStudies.init");
|
|
ok(PreferenceExperiments.init.called, "startup calls PreferenceExperiments.init");
|
|
ok(RecipeRunner.init.called, "startup calls RecipeRunner.init");
|
|
ok(TelemetryEvents.init.called, "startup calls TelemetryEvents.init");
|
|
ok(PreferenceRollouts.init.called, "startup calls PreferenceRollouts.init");
|
|
}
|
|
);
|
|
|
|
decorate_task(
|
|
withStubInits,
|
|
async function testStartupAboutPagesInitFail() {
|
|
AboutPages.init.rejects();
|
|
|
|
await Normandy.finishInit();
|
|
ok(AboutPages.init.called, "startup calls AboutPages.init");
|
|
ok(AddonStudies.init.called, "startup calls AddonStudies.init");
|
|
ok(PreferenceExperiments.init.called, "startup calls PreferenceExperiments.init");
|
|
ok(RecipeRunner.init.called, "startup calls RecipeRunner.init");
|
|
ok(TelemetryEvents.init.called, "startup calls TelemetryEvents.init");
|
|
ok(PreferenceRollouts.init.called, "startup calls PreferenceRollouts.init");
|
|
}
|
|
);
|
|
|
|
decorate_task(
|
|
withStubInits,
|
|
async function testStartupAddonStudiesInitFail() {
|
|
AddonStudies.init.rejects();
|
|
|
|
await Normandy.finishInit();
|
|
ok(AboutPages.init.called, "startup calls AboutPages.init");
|
|
ok(AddonStudies.init.called, "startup calls AddonStudies.init");
|
|
ok(PreferenceExperiments.init.called, "startup calls PreferenceExperiments.init");
|
|
ok(RecipeRunner.init.called, "startup calls RecipeRunner.init");
|
|
ok(TelemetryEvents.init.called, "startup calls TelemetryEvents.init");
|
|
ok(PreferenceRollouts.init.called, "startup calls PreferenceRollouts.init");
|
|
}
|
|
);
|
|
|
|
decorate_task(
|
|
withStubInits,
|
|
async function testStartupTelemetryEventsInitFail() {
|
|
TelemetryEvents.init.throws();
|
|
|
|
await Normandy.finishInit();
|
|
ok(AboutPages.init.called, "startup calls AboutPages.init");
|
|
ok(AddonStudies.init.called, "startup calls AddonStudies.init");
|
|
ok(PreferenceExperiments.init.called, "startup calls PreferenceExperiments.init");
|
|
ok(RecipeRunner.init.called, "startup calls RecipeRunner.init");
|
|
ok(TelemetryEvents.init.called, "startup calls TelemetryEvents.init");
|
|
ok(PreferenceRollouts.init.called, "startup calls PreferenceRollouts.init");
|
|
}
|
|
);
|
|
|
|
decorate_task(
|
|
withStubInits,
|
|
async function testStartupPreferenceRolloutsInitFail() {
|
|
PreferenceRollouts.init.throws();
|
|
|
|
await Normandy.finishInit();
|
|
ok(AboutPages.init.called, "startup calls AboutPages.init");
|
|
ok(AddonStudies.init.called, "startup calls AddonStudies.init");
|
|
ok(PreferenceExperiments.init.called, "startup calls PreferenceExperiments.init");
|
|
ok(RecipeRunner.init.called, "startup calls RecipeRunner.init");
|
|
ok(TelemetryEvents.init.called, "startup calls TelemetryEvents.init");
|
|
ok(PreferenceRollouts.init.called, "startup calls PreferenceRollouts.init");
|
|
}
|
|
);
|
|
|
|
decorate_task(
|
|
withMockPreferences,
|
|
async function testPrefMigration(mockPreferences) {
|
|
const legacyPref = "extensions.shield-recipe-client.test";
|
|
const migratedPref = "app.normandy.test";
|
|
mockPreferences.set(legacyPref, 1);
|
|
|
|
ok(
|
|
Services.prefs.prefHasUserValue(legacyPref),
|
|
"Legacy pref should have a user value before running migration",
|
|
);
|
|
ok(
|
|
!Services.prefs.prefHasUserValue(migratedPref),
|
|
"Migrated pref should not have a user value before running migration",
|
|
);
|
|
|
|
Normandy.migrateShieldPrefs();
|
|
|
|
ok(
|
|
!Services.prefs.prefHasUserValue(legacyPref),
|
|
"Legacy pref should not have a user value after running migration",
|
|
);
|
|
ok(
|
|
Services.prefs.prefHasUserValue(migratedPref),
|
|
"Migrated pref should have a user value after running migration",
|
|
);
|
|
is(Services.prefs.getIntPref(migratedPref), 1, "Value should have been migrated");
|
|
|
|
Services.prefs.clearUserPref(migratedPref);
|
|
},
|
|
);
|