Bug 1548520 - Add user telemetry for Bookmark Panel messages r=nanj

Differential Revision: https://phabricator.services.mozilla.com/D30176

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andrei Oprea 2019-05-08 15:46:42 +00:00
Родитель fabb0dc4d5
Коммит 0380dc1228
2 изменённых файлов: 49 добавлений и 20 удалений

Просмотреть файл

@ -9,6 +9,8 @@ ChromeUtils.defineModuleGetter(this, "FxAccounts",
"resource://gre/modules/FxAccounts.jsm");
ChromeUtils.defineModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
class _BookmarkPanelHub {
constructor() {
@ -62,7 +64,7 @@ class _BookmarkPanelHub {
* @returns {obj|null} response object or null if no messages matched
*/
async messageRequest(target, win) {
if (this._response && this._response.url === target.url && this._response.content) {
if (this._response && this._response.win === win && this._response.url === target.url && this._response.content) {
this.showMessage(this._response.content, target, win);
return true;
}
@ -88,7 +90,7 @@ class _BookmarkPanelHub {
if (response && response.content) {
this.showMessage(response.content, target, win);
this.sendImpression();
this.sendUserEventTelemetry("IMPRESSION");
this.sendUserEventTelemetry("IMPRESSION", win);
} else {
this.hideMessage(target);
}
@ -117,7 +119,7 @@ class _BookmarkPanelHub {
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
csp: null,
});
this.sendUserEventTelemetry("CLICK");
this.sendUserEventTelemetry("CLICK", win);
});
recommendation.style.color = message.color;
recommendation.style.background = `-moz-linear-gradient(-45deg, ${message.background_color_1} 0%, ${message.background_color_2} 70%)`;
@ -126,7 +128,7 @@ class _BookmarkPanelHub {
close.setAttribute("aria-label", "close");
this._l10n.setAttributes(close, message.close_button.tooltiptext);
close.addEventListener("click", e => {
this.sendUserEventTelemetry("DISMISS");
this.sendUserEventTelemetry("DISMISS", win);
this.collapseMessage();
target.close(e);
});
@ -190,9 +192,12 @@ class _BookmarkPanelHub {
this._addImpression(this._response);
}
sendUserEventTelemetry(event) {
sendUserEventTelemetry(event, win) {
// Only send pings for non private browsing windows
if (!PrivateBrowsingUtils.isBrowserPrivate(win.ownerGlobal.gBrowser.selectedBrowser)) {
this._sendTelemetry({message_id: this._response.id, bucket_id: this._response.id, event});
}
}
_sendTelemetry(ping) {
this._dispatch({

Просмотреть файл

@ -12,6 +12,8 @@ describe("BookmarkPanelHub", () => {
let fakeTarget;
let fakeContainer;
let fakeDispatch;
let fakeWindow;
let isBrowserPrivateStub;
beforeEach(() => {
sandbox = sinon.createSandbox();
globals = new GlobalOverrider();
@ -19,6 +21,8 @@ describe("BookmarkPanelHub", () => {
fakeL10n = {setAttributes: sandbox.stub(), translateElements: sandbox.stub()};
globals.set("DOMLocalization", function() { return fakeL10n; }); // eslint-disable-line prefer-arrow-callback
globals.set("FxAccounts", {config: {promiseEmailFirstURI: sandbox.stub()}});
isBrowserPrivateStub = sandbox.stub().returns(false);
globals.set("PrivateBrowsingUtils", {isBrowserPrivate: isBrowserPrivateStub});
instance = new _BookmarkPanelHub();
fakeAddImpression = sandbox.stub();
@ -57,6 +61,7 @@ describe("BookmarkPanelHub", () => {
close: sandbox.stub(),
};
fakeDispatch = sandbox.stub();
fakeWindow = {ownerGlobal: {openLinkIn: sandbox.stub(), gBrowser: {selectedBrowser: "browser"}}};
});
afterEach(() => {
instance.uninit();
@ -126,19 +131,19 @@ describe("BookmarkPanelHub", () => {
fakeTarget = {infoButton: {disabled: true}};
});
it("should show a message when called with a response", () => {
instance.onResponse({content: "content"}, fakeTarget, {});
instance.onResponse({content: "content"}, fakeTarget, fakeWindow);
assert.calledOnce(instance.showMessage);
assert.calledWithExactly(instance.showMessage, "content", fakeTarget, {});
assert.calledWithExactly(instance.showMessage, "content", fakeTarget, fakeWindow);
assert.calledOnce(instance.sendImpression);
});
it("should dispatch a user impression", () => {
sandbox.spy(instance, "sendUserEventTelemetry");
instance.onResponse({content: "content"}, fakeTarget, {});
instance.onResponse({content: "content"}, fakeTarget, fakeWindow);
assert.calledOnce(instance.sendUserEventTelemetry);
assert.calledWithExactly(instance.sendUserEventTelemetry, "IMPRESSION");
assert.calledWithExactly(instance.sendUserEventTelemetry, "IMPRESSION", fakeWindow);
assert.calledOnce(fakeDispatch);
const [ping] = fakeDispatch.firstCall.args;
@ -146,6 +151,16 @@ describe("BookmarkPanelHub", () => {
assert.equal(ping.type, "DOORHANGER_TELEMETRY");
assert.equal(ping.data.event, "IMPRESSION");
});
it("should not dispatch a user impression if the window is private", () => {
isBrowserPrivateStub.returns(true);
sandbox.spy(instance, "sendUserEventTelemetry");
instance.onResponse({content: "content"}, fakeTarget, fakeWindow);
assert.calledOnce(instance.sendUserEventTelemetry);
assert.calledWithExactly(instance.sendUserEventTelemetry, "IMPRESSION", fakeWindow);
assert.notCalled(fakeDispatch);
});
it("should hide existing messages if no response is provided", () => {
instance.onResponse(null, fakeTarget);
@ -175,33 +190,42 @@ describe("BookmarkPanelHub", () => {
assert.notCalled(fakeTarget.container.appendChild);
});
it("should open a tab with FxA signup", async () => {
const windowStub = {ownerGlobal: {openLinkIn: sandbox.stub()}};
fakeTarget.container.querySelector.returns(false);
instance.showMessage(fakeMessage, fakeTarget, windowStub);
instance.showMessage(fakeMessage, fakeTarget, fakeWindow);
// Call the event listener cb
await fakeContainer.addEventListener.firstCall.args[1]();
assert.calledOnce(windowStub.ownerGlobal.openLinkIn);
assert.calledOnce(fakeWindow.ownerGlobal.openLinkIn);
});
it("should send a click event", async () => {
const windowStub = {ownerGlobal: {openLinkIn: sandbox.stub()}};
sandbox.stub(instance, "sendUserEventTelemetry");
fakeTarget.container.querySelector.returns(false);
instance.showMessage(fakeMessage, fakeTarget, windowStub);
instance.showMessage(fakeMessage, fakeTarget, fakeWindow);
// Call the event listener cb
await fakeContainer.addEventListener.firstCall.args[1]();
assert.calledOnce(instance.sendUserEventTelemetry);
assert.calledWithExactly(instance.sendUserEventTelemetry, "CLICK");
assert.calledWithExactly(instance.sendUserEventTelemetry, "CLICK", fakeWindow);
});
it("should send a click event", async () => {
sandbox.stub(instance, "sendUserEventTelemetry");
fakeTarget.container.querySelector.returns(false);
instance.showMessage(fakeMessage, fakeTarget, fakeWindow);
// Call the event listener cb
await fakeContainer.addEventListener.firstCall.args[1]();
assert.calledOnce(instance.sendUserEventTelemetry);
assert.calledWithExactly(instance.sendUserEventTelemetry, "CLICK", fakeWindow);
});
it("should collapse the message", () => {
fakeTarget.container.querySelector.returns(false);
sandbox.spy(instance, "collapseMessage");
instance._response.collapsed = false;
instance.showMessage(fakeMessage, fakeTarget);
instance.showMessage(fakeMessage, fakeTarget, fakeWindow);
// Show message calls it once so we need to reset
instance.toggleRecommendation.reset();
// Call the event listener cb
@ -217,15 +241,15 @@ describe("BookmarkPanelHub", () => {
sandbox.spy(instance, "collapseMessage");
instance._response.collapsed = false;
instance.showMessage(fakeMessage, fakeTarget);
instance.showMessage(fakeMessage, fakeTarget, fakeWindow);
// Call the event listener cb
fakeContainer.addEventListener.secondCall.args[1]();
assert.calledOnce(instance.sendUserEventTelemetry);
assert.calledWithExactly(instance.sendUserEventTelemetry, "DISMISS");
assert.calledWithExactly(instance.sendUserEventTelemetry, "DISMISS", fakeWindow);
});
it("should call toggleRecommendation `true`", () => {
instance.showMessage(fakeMessage, fakeTarget);
instance.showMessage(fakeMessage, fakeTarget, fakeWindow);
assert.calledOnce(instance.toggleRecommendation);
assert.calledWithExactly(instance.toggleRecommendation, true);