0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 04:02:30 +08:00
discourse/spec/jobs/clean_up_browser_pageview_events_spec.rb
Krzysztof Kotlarek d570c04302
DEV: Track browser session engagement for crawler detection (#41215)
Previously, crawler detection relied only on server-side heuristics
(request velocity, ASN, referrer ratios) with no signal of genuine human
interaction within a browser session.

This change gathers per-session interaction counts (mouse, keyboard,
touch, scroll, back/forward) plus engaged duration client-side and
upserts them into a new `browser_pageview_session_engagements` table via
a lightweight `/srv/se` beacon, giving `CrawlerScorer` a human-activity
signal to weigh against its bot heuristics.
2026-07-01 09:17:48 +08:00

63 lines
2.6 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe Jobs::CleanUpBrowserPageviewEvents do
it "does nothing when the site setting is disabled" do
SiteSetting.clean_up_browser_pageview_events = false
Fabricate(:browser_pageview_event, created_at: 4.months.ago)
Fabricate(:browser_pageview_event, created_at: 1.month.ago)
expect { described_class.new.execute({}) }.not_to change { BrowserPageviewEvent.count }
end
it "deletes events older than 3 months and keeps fresher ones" do
SiteSetting.clean_up_browser_pageview_events = true
fresh_event = Fabricate(:browser_pageview_event, created_at: 1.month.ago)
Fabricate(:browser_pageview_event, created_at: 4.months.ago)
expect { described_class.new.execute({}) }.to change { BrowserPageviewEvent.count }.by(-1)
expect(BrowserPageviewEvent.all).to contain_exactly(fresh_event)
end
it "deletes session engagements older than 3 months and keeps fresher ones" do
SiteSetting.clean_up_browser_pageview_events = true
fresh = BrowserPageviewSessionEngagement.create!(session_id: "fresh", created_at: 1.month.ago)
BrowserPageviewSessionEngagement.create!(session_id: "old", created_at: 4.months.ago)
expect { described_class.new.execute({}) }.to change {
BrowserPageviewSessionEngagement.count
}.by(-1)
expect(BrowserPageviewSessionEngagement.all).to contain_exactly(fresh)
end
it "deletes scores for deleted events" do
SiteSetting.clean_up_browser_pageview_events = true
fresh_event = Fabricate(:browser_pageview_event, created_at: 1.month.ago)
old_event = Fabricate(:browser_pageview_event, created_at: 4.months.ago)
BrowserPageviewEventScore.create!(event: fresh_event)
BrowserPageviewEventScore.create!(event: old_event)
described_class.new.execute({})
expect(BrowserPageviewEventScore.pluck(:event_id)).to contain_exactly(fresh_event.id)
end
it "keeps all events on the retention cutoff day" do
SiteSetting.clean_up_browser_pageview_events = true
freeze_time Time.zone.local(2026, 5, 28, 12, 30) do
cutoff_day_start = 3.months.ago.beginning_of_day
cutoff_day_end = 3.months.ago.end_of_day
Fabricate(:browser_pageview_event, created_at: cutoff_day_start - 1.second)
cutoff_day_first_event = Fabricate(:browser_pageview_event, created_at: cutoff_day_start)
cutoff_day_last_event = Fabricate(:browser_pageview_event, created_at: cutoff_day_end)
described_class.new.execute({})
expect(BrowserPageviewEvent.all).to contain_exactly(
cutoff_day_first_event,
cutoff_day_last_event,
)
end
end
end