REFACTOR: Abstract search link click logging (#16317)

This commit is contained in:
Penar Musaraj 2022-03-30 10:10:39 -04:00 committed by GitHub
parent 216dfbb895
commit daa581d8f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 66 additions and 23 deletions

View File

@ -1,4 +1,6 @@
import Component from "@ember/component"; import Component from "@ember/component";
import { action } from "@ember/object";
import { logSearchLinkClick } from "discourse/lib/search";
export default Component.extend({ export default Component.extend({
tagName: "div", tagName: "div",
@ -6,4 +8,15 @@ export default Component.extend({
classNameBindings: ["bulkSelectEnabled"], classNameBindings: ["bulkSelectEnabled"],
attributeBindings: ["role"], attributeBindings: ["role"],
role: "listitem", role: "listitem",
@action
logClick(topicId) {
if (this.searchLogId && topicId) {
logSearchLinkClick({
searchLogId: this.searchLogId,
searchResultId: topicId,
searchResultType: "topic",
});
}
},
}); });

View File

@ -3,6 +3,7 @@ import discourseComputed, { observes } from "discourse-common/utils/decorators";
import { import {
getSearchKey, getSearchKey,
isValidSearchTerm, isValidSearchTerm,
logSearchLinkClick,
searchContextDescription, searchContextDescription,
translateResults, translateResults,
updateRecentSearches, updateRecentSearches,
@ -470,15 +471,10 @@ export default Controller.extend({
logClick(topicId) { logClick(topicId) {
if (this.get("model.grouped_search_result.search_log_id") && topicId) { if (this.get("model.grouped_search_result.search_log_id") && topicId) {
ajax("/search/click", { logSearchLinkClick({
type: "POST", searchLogId: this.get("model.grouped_search_result.search_log_id"),
data: { searchResultId: topicId,
search_log_id: this.get( searchResultType: "topic",
"model.grouped_search_result.search_log_id"
),
search_result_id: topicId,
search_result_type: "topic",
},
}); });
} }
}, },

View File

@ -244,3 +244,14 @@ export function updateRecentSearches(currentUser, term) {
recentSearches.unshiftObject(term); recentSearches.unshiftObject(term);
currentUser.set("recent_searches", recentSearches); currentUser.set("recent_searches", recentSearches);
} }
export function logSearchLinkClick(params) {
ajax("/search/click", {
type: "POST",
data: {
search_log_id: params.searchLogId,
search_result_id: params.searchResultId,
search_result_type: params.searchResultType,
},
});
}

View File

@ -1,5 +1,11 @@
<div class="fps-result-entries" role="list"> <div class="fps-result-entries" role="list">
{{#each posts as |post|}} {{#each posts as |post|}}
{{search-result-entry post=post bulkSelectEnabled=bulkSelectEnabled selected=selected highlightQuery=highlightQuery}} {{search-result-entry
post=post
bulkSelectEnabled=bulkSelectEnabled
selected=selected
highlightQuery=highlightQuery
searchLogId=searchLogId
}}
{{/each}} {{/each}}
</div> </div>

View File

@ -131,6 +131,7 @@
bulkSelectEnabled=bulkSelectEnabled bulkSelectEnabled=bulkSelectEnabled
selected=selected selected=selected
highlightQuery=highlightQuery highlightQuery=highlightQuery
searchLogId=model.grouped_search_result.search_log_id
}} }}
{{#conditional-loading-spinner condition=loading}} {{#conditional-loading-spinner condition=loading}}

View File

@ -10,6 +10,7 @@ import { iconNode } from "discourse-common/lib/icon-library";
import { schedule } from "@ember/runloop"; import { schedule } from "@ember/runloop";
import { scrollTop } from "discourse/mixins/scroll-top"; import { scrollTop } from "discourse/mixins/scroll-top";
import { wantsNewWindow } from "discourse/lib/intercept-click"; import { wantsNewWindow } from "discourse/lib/intercept-click";
import { logSearchLinkClick } from "discourse/lib/search";
const _extraHeaderIcons = []; const _extraHeaderIcons = [];
@ -426,14 +427,7 @@ export default createWidget("header", {
const { searchLogId, searchResultId, searchResultType } = attrs; const { searchLogId, searchResultId, searchResultType } = attrs;
if (searchLogId && searchResultId && searchResultType) { if (searchLogId && searchResultId && searchResultType) {
ajax("/search/click", { logSearchLinkClick({ searchLogId, searchResultId, searchResultType });
type: "POST",
data: {
search_log_id: searchLogId,
search_result_id: searchResultId,
search_result_type: searchResultType,
},
});
} }
} }

View File

@ -6,7 +6,7 @@ import {
selectDate, selectDate,
visible, visible,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { click, fillIn, visit } from "@ember/test-helpers"; import { click, currentURL, fillIn, visit } from "@ember/test-helpers";
import { test } from "qunit"; import { test } from "qunit";
import { import {
SEARCH_TYPE_CATS_TAGS, SEARCH_TYPE_CATS_TAGS,
@ -16,6 +16,7 @@ import {
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
let lastBody; let lastBody;
let searchResultClickTracked = false;
acceptance("Search - Full Page", function (needs) { acceptance("Search - Full Page", function (needs) {
needs.user(); needs.user();
@ -95,7 +96,16 @@ acceptance("Search - Full Page", function (needs) {
server.put("/topics/bulk", (request) => { server.put("/topics/bulk", (request) => {
lastBody = helper.parsePostData(request.requestBody); lastBody = helper.parsePostData(request.requestBody);
return helper.response({ topic_ids: [7] }); return helper.response({ topic_ids: [130] });
});
server.post("/search/click", () => {
searchResultClickTracked = true;
return helper.response({ success: "OK" });
});
needs.hooks.afterEach(() => {
searchResultClickTracked = false;
}); });
}); });
@ -556,7 +566,7 @@ acceptance("Search - Full Page", function (needs) {
await click(".bulk-select-visible .btn:nth-child(2)"); // select all await click(".bulk-select-visible .btn:nth-child(2)"); // select all
await click(".bulk-select-btn"); // show bulk actions await click(".bulk-select-btn"); // show bulk actions
await click(".topic-bulk-actions-modal .btn:nth-child(2)"); // close topics await click(".topic-bulk-actions-modal .btn:nth-child(2)"); // close topics
assert.equal(lastBody["topic_ids[]"], 7); assert.equal(lastBody["topic_ids[]"], 130);
}); });
test("adds visited class to visited topics", async function (assert) { test("adds visited class to visited topics", async function (assert) {
@ -570,4 +580,16 @@ acceptance("Search - Full Page", function (needs) {
await click(".search-cta"); await click(".search-cta");
assert.equal(queryAll(".visited").length, 1); assert.equal(queryAll(".visited").length, 1);
}); });
test("result link click tracking is invoked", async function (assert) {
await visit("/search");
await fillIn(".search-query", "discourse");
await click(".search-cta");
await click("a.search-link:first-child");
assert.strictEqual(currentURL(), "/t/lorem-ipsum-dolor-sit-amet/130");
assert.ok(searchResultClickTracked);
});
}); });

View File

@ -11,12 +11,12 @@ export default {
blurb: blurb:
"The first paragraph of this pinned topic will be visible as a welcome message to all new visitors on your homepage. Its important! Edit this into a brief description of your community: Who is it for? What can they find here? Why should they come here? Where can they read more (links, resources, ...", "The first paragraph of this pinned topic will be visible as a welcome message to all new visitors on your homepage. Its important! Edit this into a brief description of your community: Who is it for? What can they find here? Why should they come here? Where can they read more (links, resources, ...",
post_number: 1, post_number: 1,
topic_id: 7, topic_id: 130,
}, },
], ],
topics: [ topics: [
{ {
id: 7, id: 130,
title: "Welcome to Discourse", title: "Welcome to Discourse",
fancy_title: "Welcome to Discourse", fancy_title: "Welcome to Discourse",
slug: "welcome-to-discourse", slug: "welcome-to-discourse",