Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { ASRouter } = ChromeUtils.importESModule(
);
const { RemoteSettings } = ChromeUtils.importESModule(
);
const { RemoteSettingsExperimentLoader } = ChromeUtils.importESModule(
);
const { ExperimentAPI } = ChromeUtils.importESModule(
);
const { ExperimentFakes, ExperimentTestUtils } = ChromeUtils.importESModule(
);
const client = RemoteSettings("nimbus-desktop-experiments");
const TEST_MESSAGE_CONTENT = {
id: "ON_LOAD_TEST_MESSAGE",
template: "cfr_doorhanger",
content: {
bucket_id: "ON_LOAD_TEST_MESSAGE",
anchor_id: "PanelUI-menu-button",
layout: "icon_and_message",
icon_dark_theme:
icon_class: "cfr-doorhanger-small-icon",
heading_text: "Heading",
text: "Text",
buttons: {
primary: {
label: { value: "Primary CTA", attributes: { accesskey: "P" } },
action: { navigate: true },
},
secondary: [
{
label: { value: "Secondary CTA", attributes: { accesskey: "S" } },
action: { type: "CANCEL" },
},
],
},
skip_address_bar_notifier: true,
},
targeting: "true",
trigger: { id: "messagesLoaded" },
};
add_task(async function test_messagesLoaded_reach_experiment() {
const sandbox = sinon.createSandbox();
const sendTriggerSpy = sandbox.spy(ASRouter, "sendTriggerMessage");
const routeSpy = sandbox.spy(ASRouter, "routeCFRMessage");
const reachSpy = sandbox.spy(ASRouter, "_recordReachEvent");
const triggerMatch = sandbox.match({ id: "messagesLoaded" });
const featureId = "cfr";
const recipe = ExperimentFakes.recipe(
`messages_loaded_test_${Services.uuid
.generateUUID()
.toString()
.slice(1, -1)}`,
{
id: `messages-loaded-test`,
bucketConfig: {
count: 100,
start: 0,
total: 100,
namespace: "mochitest",
randomizationUnit: "normandy_id",
},
branches: [
{
slug: "control",
ratio: 1,
features: [
{
featureId,
value: { ...TEST_MESSAGE_CONTENT, id: "messages-loaded-test-1" },
},
],
},
{
slug: "treatment",
ratio: 1,
features: [
{
featureId,
value: { ...TEST_MESSAGE_CONTENT, id: "messages-loaded-test-2" },
},
],
},
],
}
);
Assert.ok(
await ExperimentTestUtils.validateExperiment(recipe),
"Valid recipe"
);
await client.db.importChanges({}, Date.now(), [recipe], { clear: true });
await SpecialPowers.pushPrefEnv({
set: [
["app.shield.optoutstudies.enabled", true],
["datareporting.healthreport.uploadEnabled", true],
[
"browser.newtabpage.activity-stream.asrouter.providers.messaging-experiments",
`{"id":"messaging-experiments","enabled":true,"type":"remote-experiments","updateCycleInMs":0}`,
],
],
});
await RemoteSettingsExperimentLoader.updateRecipes();
await BrowserTestUtils.waitForCondition(
() => ExperimentAPI.getExperiment({ featureId }),
"ExperimentAPI should return an experiment"
);
await ASRouter._updateMessageProviders();
await ASRouter.loadMessagesFromAllProviders();
const filterFn = m =>
["messages-loaded-test-1", "messages-loaded-test-2"].includes(m?.id);
await BrowserTestUtils.waitForCondition(
() => ASRouter.state.messages.filter(filterFn).length > 1,
"Should load the test messages"
);
Assert.ok(sendTriggerSpy.calledWith(triggerMatch, true), "Trigger fired");
Assert.ok(
routeSpy.calledWith(
sandbox.match(filterFn),
gBrowser.selectedBrowser,
triggerMatch
),
"Trigger routed to the correct message"
);
Assert.ok(
reachSpy.calledWith(sandbox.match(filterFn)),
"Trigger recorded a reach event"
);
Assert.ok(
ASRouter.state.messages.find(m => filterFn(m) && m.forReachEvent)
?.forReachEvent.sent,
"Reach message will not be sent again"
);
sandbox.restore();
await client.db.clear();
await SpecialPowers.popPrefEnv();
await ASRouter._updateMessageProviders();
});