mirror of
https://github.com/discourse/discourse.git
synced 2025-05-30 23:38:29 +08:00
FEATURE: Only count topic views for explicit/deferred tracked views (#27533)
Followup 2f2da7274732cba30d03b6c5c3a4194652cb6783 This commit moves topic view tracking from happening every time a Topic is requested, which is susceptible to inflating numbers of views from web crawlers, to our request tracker middleware. In this new location, topic views are only tracked when the following headers are sent: * HTTP_DISCOURSE_TRACK_VIEW - This is sent on every page navigation when clicking around the ember app. We count these as browser page views because we know it comes from the AJAX call in our app. The topic ID is extracted from HTTP_DISCOURSE_TRACK_VIEW_TOPIC_ID * HTTP_DISCOURSE_DEFERRED_TRACK_VIEW - Sent when MessageBus initializes after first loading the page to count the initial page load view. The topic ID is extracted from HTTP_DISCOURSE_DEFERRED_TRACK_VIEW. This will bring topic views more in line with the change we made to page views in the referenced commit and result in more realistic topic view counts.
This commit is contained in:
@ -75,11 +75,11 @@ describe "Topic Map - Private Message", type: :system do
|
||||
expect(topic_map.expanded_map_avatars_details.length).to eq 4
|
||||
|
||||
# views count
|
||||
expect {
|
||||
sign_in(other_user)
|
||||
topic_page.visit_topic(topic)
|
||||
page.refresh
|
||||
}.to change(topic_map, :views_count).by 1
|
||||
sign_in(other_user)
|
||||
topic_page.visit_topic(topic)
|
||||
try_until_success { expect(TopicViewItem.count).to eq(2) }
|
||||
page.refresh
|
||||
expect(topic_map.views_count).to eq(2)
|
||||
|
||||
# likes count
|
||||
expect(topic_map).to have_no_likes
|
||||
|
@ -1,6 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe "request tracking", type: :system do
|
||||
describe "Request tracking", type: :system do
|
||||
before do
|
||||
ApplicationRequest.enable
|
||||
CachedCounting.reset
|
||||
@ -13,176 +13,262 @@ describe "request tracking", type: :system do
|
||||
CachedCounting.disable
|
||||
end
|
||||
|
||||
it "tracks an anonymous visit correctly" do
|
||||
visit "/"
|
||||
describe "pageviews" do
|
||||
it "tracks an anonymous visit correctly" do
|
||||
visit "/"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
|
||||
find(".nav-item_categories a").click
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 2,
|
||||
"page_view_anon_browser_total" => 2,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
find(".nav-item_categories a").click
|
||||
it "tracks a crawler visit correctly" do
|
||||
# Can't change Selenium's user agent... so change site settings to make Discourse detect chrome as a crawler
|
||||
SiteSetting.crawler_user_agents += "|chrome"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 2,
|
||||
"page_view_anon_browser_total" => 2,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
visit "/"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 1,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks a logged-in session correctly" do
|
||||
sign_in Fabricate(:user)
|
||||
|
||||
visit "/"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 1,
|
||||
"page_view_crawler_total" => 0,
|
||||
"page_view_logged_in_browser_total" => 1,
|
||||
)
|
||||
end
|
||||
|
||||
find(".nav-item_categories a").click
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 2,
|
||||
"page_view_crawler_total" => 0,
|
||||
"page_view_logged_in_browser_total" => 2,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks normal error pages correctly" do
|
||||
SiteSetting.bootstrap_error_pages = false
|
||||
|
||||
visit "/foobar"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
|
||||
# Does not count error as a pageview
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"http_4xx_total" => 1,
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
|
||||
find("#site-logo").click
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"http_4xx_total" => 1,
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks non-ember pages correctly" do
|
||||
visit "/safe-mode"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
|
||||
# Does not count error as a pageview
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks bootstrapped error pages correctly" do
|
||||
SiteSetting.bootstrap_error_pages = true
|
||||
|
||||
visit "/foobar"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
|
||||
# Does not count error as a pageview
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"http_4xx_total" => 1,
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
|
||||
find("#site-logo").click
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"http_4xx_total" => 1,
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks published pages correctly" do
|
||||
SiteSetting.enable_page_publishing = true
|
||||
page =
|
||||
Fabricate(:published_page, public: true, slug: "some-page", topic: Fabricate(:post).topic)
|
||||
|
||||
visit "/pub/some-page"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
|
||||
# Does not count error as a pageview
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks a crawler visit correctly" do
|
||||
# Can't change Selenium's user agent... so change site settings to make Discourse detect chrome as a crawler
|
||||
SiteSetting.crawler_user_agents += "|chrome"
|
||||
describe "topic views" do
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
fab!(:topic)
|
||||
fab!(:post) { Fabricate(:post, topic: topic) }
|
||||
|
||||
visit "/"
|
||||
context "when logged in" do
|
||||
before { sign_in(current_user) }
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 1,
|
||||
)
|
||||
end
|
||||
end
|
||||
it "tracks user viewing a topic correctly with deferred tracking" do
|
||||
visit topic.url
|
||||
|
||||
it "tracks a logged-in session correctly" do
|
||||
sign_in Fabricate(:user)
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(TopicViewItem.exists?(topic_id: topic.id, user_id: current_user.id)).to eq(true)
|
||||
expect(
|
||||
TopicViewStat.exists?(
|
||||
topic_id: topic.id,
|
||||
viewed_at: Time.zone.now.to_date,
|
||||
anonymous_views: 0,
|
||||
logged_in_views: 1,
|
||||
),
|
||||
).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
visit "/"
|
||||
it "tracks user viewing a topic correctly with explicit tracking" do
|
||||
visit "/"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 1,
|
||||
"page_view_crawler_total" => 0,
|
||||
"page_view_logged_in_browser_total" => 1,
|
||||
)
|
||||
find(".topic-list-item .raw-topic-link[data-topic-id='#{topic.id}']").click
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(TopicViewItem.exists?(topic_id: topic.id, user_id: current_user.id)).to eq(true)
|
||||
expect(
|
||||
TopicViewStat.exists?(
|
||||
topic_id: topic.id,
|
||||
viewed_at: Time.zone.now.to_date,
|
||||
anonymous_views: 0,
|
||||
logged_in_views: 1,
|
||||
),
|
||||
).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
find(".nav-item_categories a").click
|
||||
context "when anonymous" do
|
||||
it "tracks an anonymous user viewing a topic correctly with deferred tracking" do
|
||||
visit topic.url
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 2,
|
||||
"page_view_crawler_total" => 0,
|
||||
"page_view_logged_in_browser_total" => 2,
|
||||
)
|
||||
end
|
||||
end
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(TopicViewItem.exists?(topic_id: topic.id, user_id: nil)).to eq(true)
|
||||
expect(
|
||||
TopicViewStat.exists?(
|
||||
topic_id: topic.id,
|
||||
viewed_at: Time.zone.now.to_date,
|
||||
anonymous_views: 1,
|
||||
logged_in_views: 0,
|
||||
),
|
||||
).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks normal error pages correctly" do
|
||||
SiteSetting.bootstrap_error_pages = false
|
||||
it "tracks an anonymous user viewing a topic correctly with explicit tracking" do
|
||||
visit "/"
|
||||
|
||||
visit "/foobar"
|
||||
find(".topic-list-item .raw-topic-link[data-topic-id='#{topic.id}']").click
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
|
||||
# Does not count error as a pageview
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"http_4xx_total" => 1,
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
|
||||
find("#site-logo").click
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"http_4xx_total" => 1,
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks non-ember pages correctly" do
|
||||
visit "/safe-mode"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
|
||||
# Does not count error as a pageview
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks bootstrapped error pages correctly" do
|
||||
SiteSetting.bootstrap_error_pages = true
|
||||
|
||||
visit "/foobar"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
|
||||
# Does not count error as a pageview
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"http_4xx_total" => 1,
|
||||
"page_view_anon_total" => 0,
|
||||
"page_view_anon_browser_total" => 0,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
|
||||
find("#site-logo").click
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"http_4xx_total" => 1,
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it "tracks published pages correctly" do
|
||||
SiteSetting.enable_page_publishing = true
|
||||
page =
|
||||
Fabricate(:published_page, public: true, slug: "some-page", topic: Fabricate(:post).topic)
|
||||
|
||||
visit "/pub/some-page"
|
||||
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
|
||||
# Does not count error as a pageview
|
||||
expect(ApplicationRequest.stats).to include(
|
||||
"page_view_anon_total" => 1,
|
||||
"page_view_anon_browser_total" => 1,
|
||||
"page_view_logged_in_total" => 0,
|
||||
"page_view_crawler_total" => 0,
|
||||
)
|
||||
try_until_success do
|
||||
CachedCounting.flush
|
||||
expect(TopicViewItem.exists?(topic_id: topic.id, user_id: nil)).to eq(true)
|
||||
expect(
|
||||
TopicViewStat.exists?(
|
||||
topic_id: topic.id,
|
||||
viewed_at: Time.zone.now.to_date,
|
||||
anonymous_views: 1,
|
||||
logged_in_views: 0,
|
||||
),
|
||||
).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -63,11 +63,11 @@ describe "Topic Map", type: :system do
|
||||
expect(topic_map.expanded_map_avatars_details.length).to eq 4
|
||||
|
||||
# views count
|
||||
expect {
|
||||
sign_in(other_user)
|
||||
topic_page.visit_topic(topic)
|
||||
page.refresh
|
||||
}.to change(topic_map, :views_count).by 1
|
||||
sign_in(other_user)
|
||||
topic_page.visit_topic(topic)
|
||||
try_until_success { expect(TopicViewItem.count).to eq(2) }
|
||||
page.refresh
|
||||
expect(topic_map.views_count).to eq(2)
|
||||
|
||||
# likes count
|
||||
expect(topic_map).to have_no_likes
|
||||
|
Reference in New Issue
Block a user