Bug 1645906 - Adding telemetry to Popular Topics r=thecount

Differential Revision: https://phabricator.services.mozilla.com/D81236
This commit is contained in:
Gavin Lazar Suntop 2020-07-06 17:48:07 +00:00
Родитель d280f1f34a
Коммит 08f24d4bb1
5 изменённых файлов: 137 добавлений и 20 удалений

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

@ -168,6 +168,7 @@ export class _DiscoveryStreamBase extends React.PureComponent {
case "Navigation":
return (
<Navigation
dispatch={this.props.dispatch}
links={component.properties.links}
alignment={component.properties.alignment}
display_variant={component.properties.display_variant}

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

@ -2,15 +2,40 @@
* 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/. */
import { actionCreators as ac } from "common/Actions.jsm";
import React from "react";
import { SafeAnchor } from "../SafeAnchor/SafeAnchor";
import { FluentOrText } from "content-src/components/FluentOrText/FluentOrText";
export class Topic extends React.PureComponent {
constructor(props) {
super(props);
this.onLinkClick = this.onLinkClick.bind(this);
}
onLinkClick(event) {
if (this.props.dispatch) {
this.props.dispatch(
ac.ImpressionStats({
event: "CLICK",
source: "POPULAR_TOPICS",
value: {
topic: event.target.text.toLowerCase().replace(` `, `-`),
},
})
);
}
}
render() {
const { url, name } = this.props;
return (
<SafeAnchor className={this.props.className} url={url}>
<SafeAnchor
onLinkClick={this.onLinkClick}
className={this.props.className}
url={url}
>
{name}
</SafeAnchor>
);
@ -26,11 +51,13 @@ class ExploreTopics extends React.PureComponent {
return (
<>
<Topic
dispatch={this.props.dispatch}
className="ds-navigation-inline-explore-more"
url={explore_topics.url}
name={explore_topics.name}
/>
<Topic
dispatch={this.props.dispatch}
className="ds-navigation-header-explore-more"
url={explore_topics.url}
name={explore_topics.header}
@ -64,11 +91,18 @@ export class Navigation extends React.PureComponent {
{links &&
links.map(t => (
<li key={t.name}>
<Topic url={t.url} name={t.name} />
<Topic
url={t.url}
name={t.name}
dispatch={this.props.dispatch}
/>
</li>
))}
</ul>
<ExploreTopics explore_topics={explore_topics} />
<ExploreTopics
dispatch={this.props.dispatch}
explore_topics={explore_topics}
/>
</div>
);
}

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

@ -4379,6 +4379,7 @@ class _DiscoveryStreamBase extends react__WEBPACK_IMPORTED_MODULE_14___default.a
case "Navigation":
return react__WEBPACK_IMPORTED_MODULE_14___default.a.createElement(content_src_components_DiscoveryStreamComponents_Navigation_Navigation__WEBPACK_IMPORTED_MODULE_13__["Navigation"], {
dispatch: this.props.dispatch,
links: component.properties.links,
alignment: component.properties.alignment,
display_variant: component.properties.display_variant,
@ -10648,23 +10649,43 @@ class HorizontalRule extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCo
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Topic", function() { return Topic; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Navigation", function() { return Navigation; });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _SafeAnchor_SafeAnchor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(35);
/* harmony import */ var content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39);
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _SafeAnchor_SafeAnchor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(35);
/* harmony import */ var content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(39);
/* 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/. */
class Topic extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
class Topic extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureComponent {
constructor(props) {
super(props);
this.onLinkClick = this.onLinkClick.bind(this);
}
onLinkClick(event) {
if (this.props.dispatch) {
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].ImpressionStats({
event: "CLICK",
source: "POPULAR_TOPICS",
value: {
topic: event.target.text.toLowerCase().replace(` `, `-`)
}
}));
}
}
render() {
const {
url,
name
} = this.props;
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_SafeAnchor_SafeAnchor__WEBPACK_IMPORTED_MODULE_1__["SafeAnchor"], {
return react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(_SafeAnchor_SafeAnchor__WEBPACK_IMPORTED_MODULE_2__["SafeAnchor"], {
onLinkClick: this.onLinkClick,
className: this.props.className,
url: url
}, name);
@ -10672,7 +10693,7 @@ class Topic extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
}
class ExploreTopics extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
class ExploreTopics extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureComponent {
render() {
const {
explore_topics
@ -10682,11 +10703,13 @@ class ExploreTopics extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCom
return null;
}
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Topic, {
return react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_1___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(Topic, {
dispatch: this.props.dispatch,
className: "ds-navigation-inline-explore-more",
url: explore_topics.url,
name: explore_topics.name
}), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Topic, {
}), react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(Topic, {
dispatch: this.props.dispatch,
className: "ds-navigation-header-explore-more",
url: explore_topics.url,
name: explore_topics.header
@ -10695,7 +10718,7 @@ class ExploreTopics extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCom
}
class Navigation extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
class Navigation extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureComponent {
render() {
const {
links
@ -10712,18 +10735,20 @@ class Navigation extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureCompon
const {
explore_topics
} = this.props;
return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
return react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("div", {
className: `ds-navigation ds-navigation-${alignment} ds-navigation-variant-${variant}`
}, header.title ? react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_2__["FluentOrText"], {
}, header.title ? react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(content_src_components_FluentOrText_FluentOrText__WEBPACK_IMPORTED_MODULE_3__["FluentOrText"], {
message: header.title
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", {
}, react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("span", {
className: "ds-header"
})) : null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("ul", null, links && links.map(t => react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("li", {
})) : null, react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("ul", null, links && links.map(t => react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("li", {
key: t.name
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(Topic, {
}, react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(Topic, {
url: t.url,
name: t.name
})))), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ExploreTopics, {
name: t.name,
dispatch: this.props.dispatch
})))), react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(ExploreTopics, {
dispatch: this.props.dispatch,
explore_topics: explore_topics
}));
}

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

@ -185,6 +185,27 @@ A user event ping includes some basic metadata (tab id, addon version, etc.) as
}
```
#### Clicking a popular topic link
```js
{
"event": "CLICK",
"source": "POPULAR_TOPICS",
"value": {
"topic": ["must-reads" | "productivity" | "health" | "finance" | "technology" | "more-recommendations"]
}
// Basic metadata
"action": "activity_stream_event",
"page": ["about:newtab" | "about:home" | "about:welcome" | "unknown"],
"client_id": "26288a14-5cc4-d14f-ae0a-bb01ef45be9c",
"session_id": "005deed0-e3e4-4c02-a041-17405fd703f6",
"browser_session_id": "e7e52665-7db3-f348-9918-e93160eb2ef3",
"addon_version": "20180710100040",
"locale": "en-US",
"user_prefs": 7
}
```
#### Adding a search shortcut
```js
{

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

@ -7,6 +7,12 @@ import { SafeAnchor } from "content-src/components/DiscoveryStreamComponents/Saf
import { FluentOrText } from "content-src/components/FluentOrText/FluentOrText";
import { shallow, mount } from "enzyme";
const DEFAULT_PROPS = {
App: {
isForStartupCache: false,
},
};
describe("<Navigation>", () => {
let wrapper;
@ -51,13 +57,43 @@ describe("<Navigation>", () => {
describe("<Topic>", () => {
let wrapper;
let sandbox;
beforeEach(() => {
wrapper = shallow(<Topic url="https://foo.com" name="foo" />);
sandbox = sinon.createSandbox();
});
afterEach(() => {
sandbox.restore();
});
it("should pass onLinkClick prop", () => {
assert.propertyVal(
wrapper.at(0).props(),
"onLinkClick",
wrapper.instance().onLinkClick
);
});
it("should render", () => {
assert.ok(wrapper.exists());
assert.equal(wrapper.type(), SafeAnchor);
});
describe("onLinkClick", () => {
let dispatch;
beforeEach(() => {
dispatch = sandbox.stub();
wrapper = shallow(<Topic dispatch={dispatch} {...DEFAULT_PROPS} />);
wrapper.setState({ isSeen: true });
});
it("should call dispatch", () => {
wrapper.instance().onLinkClick({ target: { text: `Must Reads` } });
assert.calledOnce(dispatch);
});
});
});