293 lines
7.7 KiB
JavaScript
293 lines
7.7 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
const { FirefoxLabs } = ChromeUtils.importESModule(
|
|
"resource://nimbus/FirefoxLabs.sys.mjs"
|
|
);
|
|
|
|
function setupTest({ ...ctx }) {
|
|
return NimbusTestUtils.setupTest({ ...ctx, clearTelemetry: true });
|
|
}
|
|
|
|
add_setup(function () {
|
|
Services.fog.initializeFOG();
|
|
});
|
|
|
|
add_task(async function test_all() {
|
|
const { sandbox, manager, initExperimentAPI, cleanup } = await setupTest({
|
|
experiments: [
|
|
NimbusTestUtils.factories.recipe("opt-in-rollout", {
|
|
isRollout: true,
|
|
isFirefoxLabsOptIn: true,
|
|
firefoxLabsTitle: "title",
|
|
firefoxLabsDescription: "description",
|
|
firefoxLabsDescriptionLinks: null,
|
|
firefoxLabsGroup: "group",
|
|
requiresRestart: false,
|
|
}),
|
|
NimbusTestUtils.factories.recipe("opt-in-experiment", {
|
|
branches: [
|
|
{
|
|
...NimbusTestUtils.factories.recipe.branches[0],
|
|
firefoxLabsTitle: "title",
|
|
},
|
|
],
|
|
isFirefoxLabsOptIn: true,
|
|
firefoxLabsTitle: "title",
|
|
firefoxLabsDescription: "description",
|
|
firefoxLabsDescriptionLinks: null,
|
|
firefoxLabsGroup: "group",
|
|
requiresRestart: false,
|
|
}),
|
|
NimbusTestUtils.factories.recipe("targeting-fail", {
|
|
targeting: "false",
|
|
isRollout: true,
|
|
isFirefoxLabsOptIn: true,
|
|
firefoxLabsTitle: "title",
|
|
firefoxLabsDescription: "description",
|
|
firefoxLabsDescriptionLinks: null,
|
|
firefoxLabsGroup: "group",
|
|
requiresRestart: false,
|
|
}),
|
|
NimbusTestUtils.factories.recipe("bucketing-fail", {
|
|
bucketConfig: {
|
|
...NimbusTestUtils.factories.recipe.bucketConfig,
|
|
count: 0,
|
|
},
|
|
isRollout: true,
|
|
isFirefoxLabsOptIn: true,
|
|
firefoxLabsTitle: "title",
|
|
firefoxLabsDescription: "description",
|
|
firefoxLabsDescriptionLinks: null,
|
|
firefoxLabsGroup: "group",
|
|
requiresRestart: false,
|
|
}),
|
|
NimbusTestUtils.factories.recipe("experiment"),
|
|
NimbusTestUtils.factories.recipe("rollout", { isRollout: true }),
|
|
],
|
|
init: false,
|
|
});
|
|
|
|
// Stub out enrollment because we don't care.
|
|
sandbox.stub(manager, "enroll");
|
|
|
|
await initExperimentAPI();
|
|
|
|
const labs = await FirefoxLabs.create();
|
|
const availableSlugs = Array.from(labs.all(), recipe => recipe.slug).sort();
|
|
|
|
Assert.deepEqual(
|
|
availableSlugs,
|
|
["opt-in-rollout", "opt-in-experiment"].sort(),
|
|
"Should return all opt in recipes that match targeting and bucketing"
|
|
);
|
|
|
|
await cleanup();
|
|
});
|
|
|
|
add_task(async function test_enroll() {
|
|
const recipe = NimbusTestUtils.factories.recipe.withFeatureConfig(
|
|
"opt-in",
|
|
{ featureId: "nimbus-qa-1" },
|
|
{
|
|
isRollout: true,
|
|
isFirefoxLabsOptIn: true,
|
|
firefoxLabsTitle: "placeholder",
|
|
firefoxLabsDescription: "placeholder",
|
|
firefoxLabsDescriptionLinks: null,
|
|
firefoxLabsGroup: "placeholder",
|
|
requiresRestart: false,
|
|
}
|
|
);
|
|
|
|
const { sandbox, manager, initExperimentAPI, cleanup } = await setupTest({
|
|
experiments: [recipe],
|
|
init: false,
|
|
});
|
|
|
|
const enrollSpy = sandbox.spy(manager, "enroll");
|
|
|
|
await initExperimentAPI();
|
|
|
|
const labs = await FirefoxLabs.create();
|
|
|
|
await Assert.rejects(
|
|
labs.enroll(),
|
|
/enroll: slug and branchSlug are required/,
|
|
"Should throw when enroll() is called without a slug"
|
|
);
|
|
|
|
await Assert.rejects(
|
|
labs.enroll("opt-in"),
|
|
/enroll: slug and branchSlug are required/,
|
|
"Should throw when enroll() is called without a branch slug"
|
|
);
|
|
|
|
await labs.enroll("bogus", "bogus");
|
|
Assert.ok(
|
|
enrollSpy.notCalled,
|
|
"ExperimentManager.enroll not called for unknown recipe"
|
|
);
|
|
|
|
await labs.enroll(recipe.slug, "bogus");
|
|
Assert.ok(
|
|
enrollSpy.notCalled,
|
|
"ExperimentManager.enroll not called for invalid branch slug"
|
|
);
|
|
|
|
await labs.enroll(recipe.slug, recipe.branches[0].slug);
|
|
Assert.ok(
|
|
enrollSpy.calledOnceWith(recipe, "rs-loader", { branchSlug: "control" }),
|
|
"ExperimentManager.enroll called"
|
|
);
|
|
|
|
Assert.deepEqual(
|
|
Glean.nimbusEvents.enrollmentStatus
|
|
.testGetValue("events")
|
|
?.map(ev => ev.extra),
|
|
[
|
|
{
|
|
slug: recipe.slug,
|
|
branch: "control",
|
|
status: "Enrolled",
|
|
reason: "OptIn",
|
|
},
|
|
]
|
|
);
|
|
|
|
Assert.ok(manager.store.get(recipe.slug)?.active, "Active enrollment exists");
|
|
|
|
await labs.unenroll(recipe.slug);
|
|
|
|
await cleanup();
|
|
});
|
|
|
|
add_task(async function test_reenroll() {
|
|
const recipe = NimbusTestUtils.factories.recipe("opt-in", {
|
|
isFirefoxLabsOptIn: true,
|
|
firefoxLabsTitle: "placeholder",
|
|
firefoxLabsDescription: "placeholder",
|
|
firefoxLabsDescriptionLinks: null,
|
|
firefoxLabsGroup: "placeholder",
|
|
requiresRestart: false,
|
|
isRollout: true,
|
|
});
|
|
|
|
const { manager, cleanup } = await setupTest({ experiments: [recipe] });
|
|
|
|
const labs = await FirefoxLabs.create();
|
|
|
|
Assert.ok(
|
|
typeof manager.store.get(recipe.slug) === "undefined",
|
|
`No enrollment for ${recipe.slug}`
|
|
);
|
|
|
|
await labs.enroll(recipe.slug, "control");
|
|
Assert.ok(
|
|
manager.store.get(recipe.slug)?.active,
|
|
`Active enrollment for ${recipe.slug}`
|
|
);
|
|
|
|
await labs.unenroll(recipe.slug);
|
|
Assert.ok(
|
|
manager.store.get(recipe.slug)?.active === false,
|
|
`Inactive enrollment for ${recipe.slug}`
|
|
);
|
|
|
|
await ExperimentAPI._rsLoader.updateRecipes();
|
|
Assert.ok(
|
|
manager.store.get(recipe.slug)?.active === false,
|
|
`Inactive enrollment for ${recipe.slug} after updateRecipes()`
|
|
);
|
|
|
|
await labs.enroll(recipe.slug, "control");
|
|
Assert.ok(
|
|
manager.store.get(recipe.slug)?.active,
|
|
`Active enrollment for ${recipe.slug}`
|
|
);
|
|
|
|
await labs.unenroll(recipe.slug);
|
|
|
|
await cleanup();
|
|
});
|
|
|
|
add_task(async function test_unenroll() {
|
|
const { manager, cleanup } = await setupTest({
|
|
experiments: [
|
|
NimbusTestUtils.factories.recipe.withFeatureConfig(
|
|
"rollout",
|
|
{ featureId: "nimbus-qa-1" },
|
|
{ isRollout: true }
|
|
),
|
|
NimbusTestUtils.factories.recipe.withFeatureConfig(
|
|
"opt-in",
|
|
{ featureId: "nimbus-qa-2" },
|
|
{
|
|
isRollout: true,
|
|
isFirefoxLabsOptIn: true,
|
|
firefoxLabsTitle: "title",
|
|
firefoxLabsDescription: "description",
|
|
firefoxLabsDescriptionLinks: null,
|
|
firefoxLabsGroup: "group",
|
|
requiresRestart: false,
|
|
}
|
|
),
|
|
],
|
|
});
|
|
|
|
const labs = await FirefoxLabs.create();
|
|
|
|
Assert.ok(manager.store.get("rollout")?.active, "Enrolled in rollout");
|
|
Assert.ok(
|
|
typeof manager.store.get("opt-in") === "undefined",
|
|
"Did not enroll in rollout"
|
|
);
|
|
|
|
await labs.enroll("opt-in", "control");
|
|
Assert.ok(manager.store.get("opt-in")?.active, "Enrolled in opt-in");
|
|
|
|
// Should not throw.
|
|
await labs.unenroll("bogus");
|
|
|
|
// Should not throw.
|
|
await labs.unenroll("rollout");
|
|
Assert.ok(
|
|
manager.store.get("rollout").active,
|
|
"Enrolled in rollout after attempting to unenroll with incorrect API"
|
|
);
|
|
|
|
await labs.unenroll("opt-in");
|
|
Assert.ok(!manager.store.get("opt-in").active, "Unenrolled from opt-in");
|
|
|
|
// Should not throw.
|
|
await labs.unenroll("opt-in");
|
|
|
|
Assert.deepEqual(
|
|
Glean.nimbusEvents.enrollmentStatus
|
|
.testGetValue("events")
|
|
?.map(ev => ev.extra),
|
|
[
|
|
{
|
|
branch: "control",
|
|
status: "Enrolled",
|
|
slug: "rollout",
|
|
reason: "Qualified",
|
|
},
|
|
{
|
|
status: "Enrolled",
|
|
slug: "opt-in",
|
|
reason: "OptIn",
|
|
branch: "control",
|
|
},
|
|
{
|
|
branch: "control",
|
|
reason: "OptOut",
|
|
slug: "opt-in",
|
|
status: "Disqualified",
|
|
},
|
|
]
|
|
);
|
|
|
|
await manager.unenroll("rollout");
|
|
await cleanup();
|
|
});
|