diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /toolkit/components/normandy/test/browser/browser_Normandy.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/normandy/test/browser/browser_Normandy.js')
-rw-r--r-- | toolkit/components/normandy/test/browser/browser_Normandy.js | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/toolkit/components/normandy/test/browser/browser_Normandy.js b/toolkit/components/normandy/test/browser/browser_Normandy.js new file mode 100644 index 0000000000..7deba94ee8 --- /dev/null +++ b/toolkit/components/normandy/test/browser/browser_Normandy.js @@ -0,0 +1,306 @@ +"use strict"; + +const { TelemetryUtils } = ChromeUtils.importESModule( + "resource://gre/modules/TelemetryUtils.sys.mjs" +); +const { Normandy } = ChromeUtils.importESModule( + "resource://normandy/Normandy.sys.mjs" +); +const { AddonRollouts } = ChromeUtils.importESModule( + "resource://normandy/lib/AddonRollouts.sys.mjs" +); +const { PreferenceExperiments } = ChromeUtils.importESModule( + "resource://normandy/lib/PreferenceExperiments.sys.mjs" +); +const { PreferenceRollouts } = ChromeUtils.importESModule( + "resource://normandy/lib/PreferenceRollouts.sys.mjs" +); +const { RecipeRunner } = ChromeUtils.importESModule( + "resource://normandy/lib/RecipeRunner.sys.mjs" +); +const { + NormandyTestUtils: { factories }, +} = ChromeUtils.importESModule( + "resource://testing-common/NormandyTestUtils.sys.mjs" +); + +const experimentPref1 = "test.initExperimentPrefs1"; +const experimentPref2 = "test.initExperimentPrefs2"; +const experimentPref3 = "test.initExperimentPrefs3"; +const experimentPref4 = "test.initExperimentPrefs4"; + +function withStubInits() { + return function (testFunction) { + return decorate( + withStub(AddonRollouts, "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 }) { + let originalDeferred = Normandy.uiAvailableNotificationObserved; + let mockUiAvailableDeferred = Promise.withResolvers(); + Normandy.uiAvailableNotificationObserved = mockUiAvailableDeferred; + + let initPromise = Normandy.init(); + await null; + + ok( + !finishInitStub.called, + "When initialized, do not call finishInit immediately." + ); + + Normandy.observe(null, "sessionstore-windows-restored"); + await initPromise; + ok( + finishInitStub.called, + "Once the sessionstore-windows-restored event is observed, finishInit should be called." + ); + + Normandy.uiAvailableNotificationObserved = originalDeferred; + } +); + +// During startup, preferences that are changed for experiments should +// be record by calling PreferenceExperiments.recordOriginalValues. +decorate_task( + withStub(PreferenceExperiments, "recordOriginalValues", { + as: "experimentsRecordOriginalValuesStub", + }), + withStub(PreferenceRollouts, "recordOriginalValues", { + as: "rolloutsRecordOriginalValueStub", + }), + 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(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(AddonStudies.init.called, "startup calls AddonStudies.init"); + ok(AddonRollouts.init.called, "startup calls AddonRollouts.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(AddonStudies.init.called, "startup calls AddonStudies.init"); + ok(AddonRollouts.init.called, "startup calls AddonRollouts.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(AddonStudies.init.called, "startup calls AddonStudies.init"); + ok(AddonRollouts.init.called, "startup calls AddonRollouts.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(AddonStudies.init.called, "startup calls AddonStudies.init"); + ok(AddonRollouts.init.called, "startup calls AddonRollouts.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"); + } +); |