diff options
Diffstat (limited to 'toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature_getAllVariables.js')
-rw-r--r-- | toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature_getAllVariables.js | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature_getAllVariables.js b/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature_getAllVariables.js new file mode 100644 index 0000000000..fd9e09c03d --- /dev/null +++ b/toolkit/components/nimbus/test/unit/test_ExperimentAPI_ExperimentFeature_getAllVariables.js @@ -0,0 +1,249 @@ +"use strict"; + +const { ExperimentAPI, _ExperimentFeature: ExperimentFeature } = + ChromeUtils.importESModule("resource://nimbus/ExperimentAPI.sys.mjs"); +const { ExperimentFakes } = ChromeUtils.importESModule( + "resource://testing-common/NimbusTestUtils.sys.mjs" +); + +const { cleanupStorePrefCache } = ExperimentFakes; + +async function setupForExperimentFeature() { + const sandbox = sinon.createSandbox(); + const manager = ExperimentFakes.manager(); + await manager.onStartup(); + + sandbox.stub(ExperimentAPI, "_store").get(() => manager.store); + + return { sandbox, manager }; +} + +const FEATURE_ID = "aboutwelcome"; +const TEST_FALLBACK_PREF = "browser.aboutwelcome.screens"; +const FAKE_FEATURE_MANIFEST = { + variables: { + screens: { + type: "json", + fallbackPref: TEST_FALLBACK_PREF, + }, + source: { + type: "string", + }, + }, +}; + +add_task( + async function test_ExperimentFeature_getAllVariables_prefsOverDefaults() { + const { sandbox } = await setupForExperimentFeature(); + + const featureInstance = new ExperimentFeature( + FEATURE_ID, + FAKE_FEATURE_MANIFEST + ); + + Services.prefs.clearUserPref(TEST_FALLBACK_PREF); + + Assert.equal( + featureInstance.getAllVariables().screens?.length, + undefined, + "pref is not set" + ); + + Services.prefs.setStringPref(TEST_FALLBACK_PREF, "[]"); + + Assert.deepEqual( + featureInstance.getAllVariables().screens.length, + 0, + "should return the user pref value over the defaults" + ); + + Services.prefs.clearUserPref(TEST_FALLBACK_PREF); + sandbox.restore(); + } +); + +add_task( + async function test_ExperimentFeature_getAllVariables_experimentOverPref() { + const { sandbox, manager } = await setupForExperimentFeature(); + const recipe = ExperimentFakes.experiment("awexperiment", { + branch: { + slug: "treatment", + features: [ + { + featureId: "aboutwelcome", + value: { screens: ["test-value"] }, + }, + ], + }, + }); + + await manager.store.addEnrollment(recipe); + + const featureInstance = new ExperimentFeature( + FEATURE_ID, + FAKE_FEATURE_MANIFEST + ); + + Services.prefs.clearUserPref(TEST_FALLBACK_PREF); + + Assert.ok( + !!featureInstance.getAllVariables().screens, + "should return the AW experiment value" + ); + + Assert.equal( + featureInstance.getAllVariables().screens[0], + "test-value", + "should return the AW experiment value" + ); + + Services.prefs.setStringPref(TEST_FALLBACK_PREF, "[]"); + Assert.equal( + featureInstance.getAllVariables().screens[0], + "test-value", + "should return the AW experiment value" + ); + + await ExperimentFakes.cleanupAll([recipe.slug], { manager }); + Assert.deepEqual( + featureInstance.getAllVariables().screens.length, + 0, + "should return the user pref value" + ); + + Services.prefs.clearUserPref(TEST_FALLBACK_PREF); + sandbox.restore(); + } +); + +add_task( + async function test_ExperimentFeature_getAllVariables_experimentOverRemote() { + Services.prefs.clearUserPref(TEST_FALLBACK_PREF); + const { manager } = await setupForExperimentFeature(); + const featureInstance = new ExperimentFeature( + FEATURE_ID, + FAKE_FEATURE_MANIFEST + ); + const recipe = ExperimentFakes.experiment("aw-experiment", { + branch: { + slug: "treatment", + features: [ + { + featureId: FEATURE_ID, + value: { screens: ["test-value"] }, + }, + ], + }, + }); + const rollout = ExperimentFakes.rollout("aw-rollout", { + branch: { + slug: "treatment", + features: [ + { featureId: FEATURE_ID, value: { screens: [], source: "rollout" } }, + ], + }, + }); + // We're using the store in this test we need to wait for it to load + await manager.store.ready(); + + const rolloutPromise = new Promise(resolve => + featureInstance.onUpdate((feature, reason) => { + if (reason === "rollout-updated") { + resolve(); + } + }) + ); + const experimentPromise = new Promise(resolve => + featureInstance.onUpdate((feature, reason) => { + if (reason === "experiment-updated") { + resolve(); + } + }) + ); + manager.store.addEnrollment(recipe); + manager.store.addEnrollment(rollout); + await rolloutPromise; + await experimentPromise; + + let allVariables = featureInstance.getAllVariables(); + + Assert.equal(allVariables.screens.length, 1, "Returns experiment value"); + Assert.ok(!allVariables.source, "Does not include rollout value"); + + await ExperimentFakes.cleanupAll([recipe.slug], { manager }); + cleanupStorePrefCache(); + } +); + +add_task( + async function test_ExperimentFeature_getAllVariables_rolloutOverPrefDefaults() { + const { manager } = await setupForExperimentFeature(); + const featureInstance = new ExperimentFeature( + FEATURE_ID, + FAKE_FEATURE_MANIFEST + ); + const rollout = ExperimentFakes.rollout("foo-aw", { + branch: { + slug: "getAllVariables", + features: [{ featureId: FEATURE_ID, value: { screens: [] } }], + }, + }); + // We're using the store in this test we need to wait for it to load + await manager.store.ready(); + + Services.prefs.clearUserPref(TEST_FALLBACK_PREF); + + Assert.equal( + featureInstance.getAllVariables().screens?.length, + undefined, + "Pref is not set" + ); + + const updatePromise = new Promise(resolve => + featureInstance.onUpdate(resolve) + ); + // Load remote defaults + manager.store.addEnrollment(rollout); + + // Wait for feature to load the rollout + await updatePromise; + + Assert.deepEqual( + featureInstance.getAllVariables().screens?.length, + 0, + "Should return the rollout value over the defaults" + ); + + Services.prefs.setStringPref(TEST_FALLBACK_PREF, "[1,2,3]"); + + Assert.deepEqual( + featureInstance.getAllVariables().screens.length, + 0, + "should return the rollout value over the user pref" + ); + + Services.prefs.clearUserPref(TEST_FALLBACK_PREF); + cleanupStorePrefCache(); + } +); + +add_task( + async function test_ExperimentFeature_getAllVariables_defaultValuesParam() { + const { manager } = await setupForExperimentFeature(); + const featureInstance = new ExperimentFeature( + FEATURE_ID, + FAKE_FEATURE_MANIFEST + ); + // We're using the store in this test we need to wait for it to load + await manager.store.ready(); + + Services.prefs.clearUserPref(TEST_FALLBACK_PREF); + + Assert.equal( + featureInstance.getAllVariables({ defaultValues: { screens: null } }) + .screens, + null, + "should return defaultValues param over default pref settings" + ); + } +); |