344 lines
10 KiB
JavaScript
344 lines
10 KiB
JavaScript
import { GlobalOverrider } from "tests/unit/utils";
|
|
import { PanelTestProvider } from "modules/PanelTestProvider.sys.mjs";
|
|
import { _MomentsPageHub } from "modules/MomentsPageHub.sys.mjs";
|
|
const HOMEPAGE_OVERRIDE_PREF = "browser.startup.homepage_override.once";
|
|
|
|
describe("MomentsPageHub", () => {
|
|
let globals;
|
|
let sandbox;
|
|
let instance;
|
|
let handleMessageRequestStub;
|
|
let addImpressionStub;
|
|
let blockMessageByIdStub;
|
|
let sendTelemetryStub;
|
|
let getStringPrefStub;
|
|
let setStringPrefStub;
|
|
let setIntervalStub;
|
|
let clearIntervalStub;
|
|
|
|
beforeEach(async () => {
|
|
globals = new GlobalOverrider();
|
|
sandbox = sinon.createSandbox();
|
|
instance = new _MomentsPageHub();
|
|
const messages = (await PanelTestProvider.getMessages()).filter(
|
|
({ template }) => template === "update_action"
|
|
);
|
|
handleMessageRequestStub = sandbox.stub().resolves(messages);
|
|
addImpressionStub = sandbox.stub();
|
|
blockMessageByIdStub = sandbox.stub();
|
|
getStringPrefStub = sandbox.stub();
|
|
setStringPrefStub = sandbox.stub();
|
|
setIntervalStub = sandbox.stub();
|
|
clearIntervalStub = sandbox.stub();
|
|
sendTelemetryStub = sandbox.stub();
|
|
globals.set({
|
|
setInterval: setIntervalStub,
|
|
clearInterval: clearIntervalStub,
|
|
Services: {
|
|
prefs: {
|
|
getStringPref: getStringPrefStub,
|
|
setStringPref: setStringPrefStub,
|
|
},
|
|
},
|
|
Glean: {
|
|
messagingExperiments: {
|
|
reachMomentsPage: {
|
|
record: () => {},
|
|
},
|
|
},
|
|
messagingSystem: {
|
|
messageRequestTime: {
|
|
start() {},
|
|
stopAndAccumulate() {},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
sandbox.restore();
|
|
globals.restore();
|
|
});
|
|
|
|
it("should create an instance", async () => {
|
|
setIntervalStub.returns(42);
|
|
assert.ok(instance);
|
|
await instance.init(Promise.resolve(), {
|
|
handleMessageRequest: handleMessageRequestStub,
|
|
addImpression: addImpressionStub,
|
|
blockMessageById: blockMessageByIdStub,
|
|
});
|
|
assert.equal(instance.state._intervalId, 42);
|
|
});
|
|
|
|
it("should init only once", async () => {
|
|
assert.notCalled(handleMessageRequestStub);
|
|
|
|
await instance.init(Promise.resolve(), {
|
|
handleMessageRequest: handleMessageRequestStub,
|
|
addImpression: addImpressionStub,
|
|
blockMessageById: blockMessageByIdStub,
|
|
});
|
|
await instance.init(Promise.resolve(), {
|
|
handleMessageRequest: handleMessageRequestStub,
|
|
addImpression: addImpressionStub,
|
|
blockMessageById: blockMessageByIdStub,
|
|
});
|
|
|
|
assert.calledOnce(handleMessageRequestStub);
|
|
|
|
instance.uninit();
|
|
|
|
await instance.init(Promise.resolve(), {
|
|
handleMessageRequest: handleMessageRequestStub,
|
|
addImpression: addImpressionStub,
|
|
blockMessageById: blockMessageByIdStub,
|
|
});
|
|
|
|
assert.calledTwice(handleMessageRequestStub);
|
|
});
|
|
|
|
it("should uninit the instance", () => {
|
|
instance.uninit();
|
|
assert.calledOnce(clearIntervalStub);
|
|
});
|
|
|
|
it("should setInterval for `checkHomepageOverridePref`", async () => {
|
|
await instance.init(sandbox.stub().resolves(), {});
|
|
sandbox.stub(instance, "checkHomepageOverridePref");
|
|
|
|
assert.calledOnce(setIntervalStub);
|
|
assert.calledWithExactly(setIntervalStub, sinon.match.func, 5 * 60 * 1000);
|
|
|
|
assert.notCalled(instance.checkHomepageOverridePref);
|
|
const [cb] = setIntervalStub.firstCall.args;
|
|
|
|
cb();
|
|
|
|
assert.calledOnce(instance.checkHomepageOverridePref);
|
|
});
|
|
|
|
describe("#messageRequest", () => {
|
|
beforeEach(async () => {
|
|
await instance.init(Promise.resolve(), {
|
|
handleMessageRequest: handleMessageRequestStub,
|
|
addImpression: addImpressionStub,
|
|
blockMessageById: blockMessageByIdStub,
|
|
sendTelemetry: sendTelemetryStub,
|
|
});
|
|
});
|
|
afterEach(() => {
|
|
instance.uninit();
|
|
});
|
|
it("should fetch a message with the provided trigger and template", async () => {
|
|
await instance.messageRequest({
|
|
triggerId: "trigger",
|
|
template: "template",
|
|
});
|
|
|
|
assert.calledTwice(handleMessageRequestStub);
|
|
assert.calledWithExactly(handleMessageRequestStub, {
|
|
triggerId: "trigger",
|
|
template: "template",
|
|
returnAll: true,
|
|
});
|
|
});
|
|
it("shouldn't do anything if no message is provided", async () => {
|
|
// Reset the call from `instance.init`
|
|
setStringPrefStub.reset();
|
|
handleMessageRequestStub.resolves([]);
|
|
await instance.messageRequest({ triggerId: "trigger" });
|
|
|
|
assert.notCalled(setStringPrefStub);
|
|
});
|
|
it("should record a message request time", async () => {
|
|
const fakeTimerId = 42;
|
|
const start = sandbox
|
|
.stub(global.Glean.messagingSystem.messageRequestTime, "start")
|
|
.returns(fakeTimerId);
|
|
const stopAndAccumulate = sandbox.stub(
|
|
global.Glean.messagingSystem.messageRequestTime,
|
|
"stopAndAccumulate"
|
|
);
|
|
|
|
await instance.messageRequest({ triggerId: "trigger" });
|
|
|
|
assert.calledOnce(start);
|
|
assert.calledWithExactly(start);
|
|
assert.calledOnce(stopAndAccumulate);
|
|
assert.calledWithExactly(stopAndAccumulate, fakeTimerId);
|
|
});
|
|
it("should record Reach event for the Moments page experiment", async () => {
|
|
const momentsMessages = (await PanelTestProvider.getMessages()).filter(
|
|
({ template }) => template === "update_action"
|
|
);
|
|
const messages = [
|
|
{
|
|
forReachEvent: { sent: false },
|
|
experimentSlug: "foo",
|
|
branchSlug: "bar",
|
|
},
|
|
...momentsMessages,
|
|
];
|
|
handleMessageRequestStub.resolves(messages);
|
|
sandbox.spy(global.Glean.messagingExperiments.reachMomentsPage, "record");
|
|
sandbox.spy(instance, "executeAction");
|
|
|
|
await instance.messageRequest({ triggerId: "trigger" });
|
|
|
|
assert.calledOnce(
|
|
global.Glean.messagingExperiments.reachMomentsPage.record
|
|
);
|
|
assert.calledOnce(instance.executeAction);
|
|
});
|
|
it("should not record the Reach event if it's already sent", async () => {
|
|
const messages = [
|
|
{
|
|
forReachEvent: { sent: true },
|
|
experimentSlug: "foo",
|
|
branchSlug: "bar",
|
|
},
|
|
];
|
|
handleMessageRequestStub.resolves(messages);
|
|
sandbox.spy(global.Glean.messagingExperiments.reachMomentsPage, "record");
|
|
|
|
await instance.messageRequest({ triggerId: "trigger" });
|
|
|
|
assert.notCalled(
|
|
global.Glean.messagingExperiments.reachMomentsPage.record
|
|
);
|
|
});
|
|
it("should not trigger the action if it's only for the Reach event", async () => {
|
|
const messages = [
|
|
{
|
|
forReachEvent: { sent: false },
|
|
experimentSlug: "foo",
|
|
branchSlug: "bar",
|
|
},
|
|
];
|
|
handleMessageRequestStub.resolves(messages);
|
|
sandbox.spy(global.Glean.messagingExperiments.reachMomentsPage, "record");
|
|
sandbox.spy(instance, "executeAction");
|
|
|
|
await instance.messageRequest({ triggerId: "trigger" });
|
|
|
|
assert.calledOnce(
|
|
global.Glean.messagingExperiments.reachMomentsPage.record
|
|
);
|
|
assert.notCalled(instance.executeAction);
|
|
});
|
|
});
|
|
describe("executeAction", () => {
|
|
beforeEach(async () => {
|
|
blockMessageByIdStub = sandbox.stub();
|
|
await instance.init(sandbox.stub().resolves(), {
|
|
addImpression: addImpressionStub,
|
|
blockMessageById: blockMessageByIdStub,
|
|
sendTelemetry: sendTelemetryStub,
|
|
});
|
|
});
|
|
it("should set HOMEPAGE_OVERRIDE_PREF on `moments-wnp` action", async () => {
|
|
const [msg] = await handleMessageRequestStub();
|
|
sandbox.useFakeTimers();
|
|
instance.executeAction(msg);
|
|
|
|
assert.calledOnce(setStringPrefStub);
|
|
assert.calledWithExactly(
|
|
setStringPrefStub,
|
|
HOMEPAGE_OVERRIDE_PREF,
|
|
JSON.stringify({
|
|
message_id: msg.id,
|
|
url: msg.content.action.data.url,
|
|
expire: instance.getExpirationDate(
|
|
msg.content.action.data.expireDelta
|
|
),
|
|
})
|
|
);
|
|
});
|
|
it("should block after taking the action", async () => {
|
|
const [msg] = await handleMessageRequestStub();
|
|
instance.executeAction(msg);
|
|
|
|
assert.calledOnce(blockMessageByIdStub);
|
|
assert.calledWithExactly(blockMessageByIdStub, msg.id);
|
|
});
|
|
it("should compute expire based on expireDelta", async () => {
|
|
sandbox.spy(instance, "getExpirationDate");
|
|
|
|
const [msg] = await handleMessageRequestStub();
|
|
instance.executeAction(msg);
|
|
|
|
assert.calledOnce(instance.getExpirationDate);
|
|
assert.calledWithExactly(
|
|
instance.getExpirationDate,
|
|
msg.content.action.data.expireDelta
|
|
);
|
|
});
|
|
it("should compute expire based on expireDelta", async () => {
|
|
sandbox.spy(instance, "getExpirationDate");
|
|
|
|
const [msg] = await handleMessageRequestStub();
|
|
const msgWithExpire = {
|
|
...msg,
|
|
content: {
|
|
...msg.content,
|
|
action: {
|
|
...msg.content.action,
|
|
data: { ...msg.content.action.data, expire: 41 },
|
|
},
|
|
},
|
|
};
|
|
instance.executeAction(msgWithExpire);
|
|
|
|
assert.notCalled(instance.getExpirationDate);
|
|
assert.calledOnce(setStringPrefStub);
|
|
assert.calledWithExactly(
|
|
setStringPrefStub,
|
|
HOMEPAGE_OVERRIDE_PREF,
|
|
JSON.stringify({
|
|
message_id: msg.id,
|
|
url: msg.content.action.data.url,
|
|
expire: 41,
|
|
})
|
|
);
|
|
});
|
|
it("should send user telemetry", async () => {
|
|
const [msg] = await handleMessageRequestStub();
|
|
const sendUserEventTelemetrySpy = sandbox.spy(
|
|
instance,
|
|
"sendUserEventTelemetry"
|
|
);
|
|
instance.executeAction(msg);
|
|
|
|
assert.calledOnce(sendTelemetryStub);
|
|
assert.calledWithExactly(sendUserEventTelemetrySpy, msg);
|
|
assert.calledWithExactly(sendTelemetryStub, {
|
|
type: "MOMENTS_PAGE_TELEMETRY",
|
|
data: {
|
|
action: "moments_user_event",
|
|
bucket_id: "WNP_THANK_YOU",
|
|
event: "MOMENTS_PAGE_SET",
|
|
message_id: "WNP_THANK_YOU",
|
|
},
|
|
});
|
|
});
|
|
});
|
|
describe("#checkHomepageOverridePref", () => {
|
|
let messageRequestStub;
|
|
beforeEach(() => {
|
|
messageRequestStub = sandbox.stub(instance, "messageRequest");
|
|
});
|
|
it("should catch parse errors", () => {
|
|
getStringPrefStub.returns({});
|
|
|
|
instance.checkHomepageOverridePref();
|
|
|
|
assert.calledOnce(messageRequestStub);
|
|
assert.calledWithExactly(messageRequestStub, {
|
|
template: "update_action",
|
|
triggerId: "momentsUpdate",
|
|
});
|
|
});
|
|
});
|
|
});
|