Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Errors
- This test gets skipped with pattern: os == 'android' OR appname == 'thunderbird'
- This test failed 10 times in the preceding 30 days. quicksearch this test
- Manifest: toolkit/components/nimbus/test/unit/xpcshell.toml
"use strict";
const FEATURE_ID = "testfeature1";
// Note: this gets deleted at the end of tests
const TEST_PREF_BRANCH = "testfeature1.";
const TEST_FEATURE = new ExperimentFeature(FEATURE_ID, {
variables: {
enabled: {
type: "boolean",
fallbackPref: `${TEST_PREF_BRANCH}enabled`,
},
name: {
type: "string",
fallbackPref: `${TEST_PREF_BRANCH}name`,
},
count: {
type: "int",
fallbackPref: `${TEST_PREF_BRANCH}count`,
},
items: {
type: "json",
fallbackPref: `${TEST_PREF_BRANCH}items`,
},
jsonNoFallback: {
type: "json",
},
},
});
add_setup(() => {
const cleanupFeature = NimbusTestUtils.addTestFeatures(TEST_FEATURE);
registerCleanupFunction(() => {
cleanupFeature();
});
});
add_task(async function test_ExperimentFeature_getFallbackPrefName() {
Assert.equal(
TEST_FEATURE.getFallbackPrefName("enabled"),
"testfeature1.enabled",
"should return the fallback preference name"
);
});
add_task(
{
skip_if: () => !AppConstants.NIGHTLY_BUILD,
},
async function test_ExperimentFeature_getVariable_notRegistered() {
Assert.throws(
() => {
TEST_FEATURE.getVariable("non_existant_variable");
},
/Nimbus: Warning - variable "non_existant_variable" is not defined in FeatureManifest\.yaml/,
"should throw in automation for variables not defined in the manifest"
);
}
);
add_task(async function test_ExperimentFeature_getVariable_noFallbackPref() {
const { cleanup } = await NimbusTestUtils.setupTest();
Assert.equal(
TEST_FEATURE.getVariable("jsonNoFallback"),
undefined,
"should return undefined if no values are set and no fallback pref is defined"
);
await cleanup();
});
add_task(async function test_ExperimentFeature_getVariable_precedence() {
const { manager, cleanup } = await NimbusTestUtils.setupTest();
const prefName = TEST_FEATURE.manifest.variables.items.fallbackPref;
const rollout = NimbusTestUtils.factories.recipe.withFeatureConfig(
`${FEATURE_ID}-rollout`,
{
branchSlug: "slug",
featureId: FEATURE_ID,
value: { items: [4, 5, 6] },
},
{ isRollout: true }
);
Services.prefs.clearUserPref(prefName);
Assert.equal(
TEST_FEATURE.getVariable("items"),
undefined,
"should return undefined if the fallback pref is not set"
);
// Default pref values
Services.prefs.setStringPref(prefName, JSON.stringify([1, 2, 3]));
Assert.deepEqual(
TEST_FEATURE.getVariable("items"),
[1, 2, 3],
"should return the default pref value"
);
await manager.enroll(rollout, "test");
Assert.deepEqual(
TEST_FEATURE.getVariable("items"),
[4, 5, 6],
"should return the remote default value over the default pref value"
);
// Experiment values
const doExperimentCleanup = await NimbusTestUtils.enrollWithFeatureConfig(
{
featureId: FEATURE_ID,
value: {
items: [7, 8, 9],
},
},
{ manager }
);
Assert.deepEqual(
TEST_FEATURE.getVariable("items"),
[7, 8, 9],
"should return the experiment value over the remote value"
);
Services.prefs.deleteBranch(TEST_PREF_BRANCH);
doExperimentCleanup();
manager.unenroll(rollout.slug);
await cleanup();
});
add_task(async function test_ExperimentFeature_getVariable_partial_values() {
const { manager, cleanup } = await NimbusTestUtils.setupTest();
const rollout = NimbusTestUtils.factories.recipe.withFeatureConfig(
`${FEATURE_ID}-rollout`,
{
branchSlug: "slug",
featureId: FEATURE_ID,
value: { name: "abc" },
},
{ isRollout: true }
);
// Set up a pref value for .enabled,
// a remote value for .name,
// an experiment value for .items
Services.prefs.setBoolPref(
TEST_FEATURE.manifest.variables.enabled.fallbackPref,
true
);
await manager.enroll(rollout, "test");
const doExperimentCleanup = await NimbusTestUtils.enrollWithFeatureConfig(
{
featureId: FEATURE_ID,
value: {},
},
{ manager }
);
Assert.equal(
TEST_FEATURE.getVariable("enabled"),
true,
"should skip missing variables from remote defaults"
);
Assert.equal(
TEST_FEATURE.getVariable("name"),
"abc",
"should skip missing variables from experiments"
);
Services.prefs.getDefaultBranch(null).deleteBranch(TEST_PREF_BRANCH);
Services.prefs.deleteBranch(TEST_PREF_BRANCH);
doExperimentCleanup();
manager.unenroll(rollout.slug);
await cleanup();
});
add_task(async function testGetVariableCoenrolling() {
const cleanupFeature = NimbusTestUtils.addTestFeatures(
new ExperimentFeature("foo", {
allowCoenrollment: true,
variables: {
bar: {
type: "string",
},
},
})
);
Assert.throws(
() => NimbusFeatures.foo.getVariable("bar"),
/Co-enrolling features must use the getAllEnrollments API/
);
cleanupFeature();
});