forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			249 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			249 lines
		
	
	
	
		
			6.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"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"
 | 
						|
    );
 | 
						|
  }
 | 
						|
);
 |