357 lines
8.5 KiB
Ruby
357 lines
8.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "spec_helper"
|
|
|
|
RSpec.describe ProductAnalyticsTracking, :snowplow, feature_category: :product_analytics do
|
|
include TrackingHelpers
|
|
include SnowplowHelpers
|
|
|
|
let(:user) { create(:user) }
|
|
let(:event_name) { 'an_event' }
|
|
let(:event_action) { 'an_action' }
|
|
let(:event_label) { 'a_label' }
|
|
let!(:group) { create(:group) }
|
|
|
|
let_it_be(:project) { create(:project) }
|
|
|
|
subject(:track_internal_event) { get :show, params: { id: 1 } }
|
|
|
|
def expect_internal_tracking(tracked_user: user)
|
|
expect(Gitlab::InternalEvents).to receive(:track_event).with(event_name,
|
|
user: tracked_user,
|
|
project: project,
|
|
namespace: project.namespace,
|
|
additional_properties: {}
|
|
).once
|
|
end
|
|
|
|
describe '.track_internal_event' do
|
|
controller(ApplicationController) do
|
|
include ProductAnalyticsTracking
|
|
|
|
skip_before_action :authenticate_user!, only: [:index]
|
|
track_internal_event :index, :show, name: 'an_event', conditions: [:custom_condition?], additional_properties: {}
|
|
|
|
def index
|
|
render html: 'index'
|
|
end
|
|
|
|
def show
|
|
render html: 'show'
|
|
end
|
|
|
|
private
|
|
|
|
def tracking_namespace_source
|
|
tracking_project_source.namespace
|
|
end
|
|
|
|
def tracking_project_source
|
|
Project.first
|
|
end
|
|
|
|
def custom_condition?
|
|
true
|
|
end
|
|
end
|
|
|
|
def expect_no_internal_tracking
|
|
expect(Gitlab::InternalEvents).not_to receive(:track_event)
|
|
end
|
|
|
|
let(:all_time_total_count) { Gitlab::Usage::EventSelectionRule.new(name: event_name, time_framed: false) }
|
|
let(:time_framed_total_count) { Gitlab::Usage::EventSelectionRule.new(name: event_name, time_framed: true) }
|
|
|
|
before do
|
|
allow(Gitlab::Tracking::EventDefinition).to receive(:internal_event_exists?).with('an_event').and_return(true)
|
|
event_definition = instance_double(
|
|
Gitlab::Tracking::EventDefinition,
|
|
event_selection_rules: [all_time_total_count, time_framed_total_count],
|
|
additional_properties: {}
|
|
)
|
|
allow(Gitlab::Tracking::EventDefinition).to receive(:find).with(event_name).and_return(event_definition)
|
|
allow(event_definition).to receive(:extra_trackers).and_return({})
|
|
end
|
|
|
|
context 'when user is logged in' do
|
|
let(:namespace) { project.namespace }
|
|
|
|
before do
|
|
sign_in(user)
|
|
end
|
|
|
|
it 'tracks the events if DNT is disabled' do
|
|
stub_do_not_track('0')
|
|
|
|
expect_internal_tracking
|
|
|
|
subject
|
|
end
|
|
|
|
it 'does not track the event if DNT is enabled' do
|
|
stub_do_not_track('1')
|
|
|
|
expect_no_internal_tracking
|
|
|
|
subject
|
|
end
|
|
|
|
it 'does not track the event if the format is not HTML' do
|
|
expect_no_internal_tracking
|
|
|
|
get :show, params: { id: 1, format: :json }
|
|
end
|
|
|
|
it 'does not track the event if a custom condition returns false' do
|
|
allow(controller).to receive(:custom_condition?).and_return(false)
|
|
|
|
expect_no_internal_tracking
|
|
|
|
subject
|
|
end
|
|
end
|
|
|
|
context 'when user is not logged in' do
|
|
let(:user) { nil }
|
|
|
|
it 'tracks internal event' do
|
|
expect_internal_tracking
|
|
|
|
get :index
|
|
end
|
|
|
|
it 'tracks total Redis counters' do
|
|
expect(all_time_total_count).to receive(:redis_key_for_date).and_call_original
|
|
expect(time_framed_total_count).to receive(:redis_key_for_date).and_call_original
|
|
|
|
get :index
|
|
end
|
|
|
|
it 'does not update unique counter' do
|
|
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
|
|
|
|
get :index
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '.track_internal_event with empty additional_properties' do
|
|
controller(ApplicationController) do
|
|
include ProductAnalyticsTracking
|
|
|
|
skip_before_action :authenticate_user!, only: [:index]
|
|
track_internal_event :index, :show, name: 'an_event', additional_properties: nil
|
|
|
|
def index
|
|
render html: 'index'
|
|
end
|
|
|
|
def show
|
|
render html: 'show'
|
|
end
|
|
|
|
private
|
|
|
|
def tracking_namespace_source
|
|
tracking_project_source.namespace
|
|
end
|
|
|
|
def tracking_project_source
|
|
Project.first
|
|
end
|
|
end
|
|
|
|
context 'when user is logged in' do
|
|
let(:namespace) { project.namespace }
|
|
|
|
before do
|
|
sign_in(user)
|
|
end
|
|
|
|
it 'tracks internal event' do
|
|
expect_internal_tracking
|
|
|
|
get :index
|
|
end
|
|
end
|
|
end
|
|
|
|
describe '.track_event' do
|
|
before do
|
|
allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event)
|
|
end
|
|
|
|
controller(ApplicationController) do
|
|
include ProductAnalyticsTracking
|
|
|
|
skip_before_action :authenticate_user!, only: :show
|
|
track_event(
|
|
:index,
|
|
:show,
|
|
name: 'an_event',
|
|
action: 'an_action',
|
|
label: 'a_label',
|
|
destinations: [:redis_hll, :snowplow],
|
|
conditions: [:custom_condition_one?, :custom_condition_two?]
|
|
) { |controller| controller.get_custom_id }
|
|
|
|
track_internal_event :internal_event, name: 'an_internal_event'
|
|
|
|
def index
|
|
render html: 'index'
|
|
end
|
|
|
|
def new
|
|
render html: 'new'
|
|
end
|
|
|
|
def show
|
|
render html: 'show'
|
|
end
|
|
|
|
def get_custom_id
|
|
'some_custom_id'
|
|
end
|
|
|
|
private
|
|
|
|
def tracking_namespace_source
|
|
Group.first
|
|
end
|
|
|
|
def tracking_project_source
|
|
Project.first
|
|
end
|
|
|
|
def custom_condition_one?
|
|
true
|
|
end
|
|
|
|
def custom_condition_two?
|
|
true
|
|
end
|
|
end
|
|
|
|
def expect_redis_hll_tracking
|
|
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to have_received(:track_event)
|
|
.with(event_name, values: instance_of(String))
|
|
end
|
|
|
|
def expect_snowplow_tracking(user)
|
|
context = Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: event_name)
|
|
.to_context.to_json
|
|
|
|
expect_snowplow_event(
|
|
category: anything,
|
|
action: event_action,
|
|
property: event_name,
|
|
label: event_label,
|
|
project: project,
|
|
namespace: group,
|
|
user: user,
|
|
context: [context]
|
|
)
|
|
end
|
|
|
|
def expect_no_tracking
|
|
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
|
|
|
|
expect_no_snowplow_event
|
|
end
|
|
|
|
context 'when user is logged in' do
|
|
before do
|
|
sign_in(user)
|
|
end
|
|
|
|
it 'tracks the event' do
|
|
get :index
|
|
|
|
expect_redis_hll_tracking
|
|
expect_snowplow_tracking(user)
|
|
end
|
|
|
|
it 'tracks the event if DNT is not enabled' do
|
|
stub_do_not_track('0')
|
|
|
|
get :index
|
|
|
|
expect_redis_hll_tracking
|
|
expect_snowplow_tracking(user)
|
|
end
|
|
|
|
it 'does not track the event if DNT is enabled' do
|
|
stub_do_not_track('1')
|
|
|
|
get :index
|
|
|
|
expect_no_tracking
|
|
end
|
|
|
|
it 'does not track the event if the format is not HTML' do
|
|
get :index, format: :json
|
|
|
|
expect_no_tracking
|
|
end
|
|
|
|
it 'does not track the event if a custom condition returns false' do
|
|
allow(controller).to receive(:custom_condition_two?).and_return(false)
|
|
|
|
get :index
|
|
|
|
expect_no_tracking
|
|
end
|
|
|
|
it 'does not track the event for untracked actions' do
|
|
get :new
|
|
|
|
expect_no_tracking
|
|
end
|
|
end
|
|
|
|
context 'when user is not logged in' do
|
|
let(:visitor_id) { SecureRandom.uuid }
|
|
|
|
it 'tracks the event when there is a visitor id' do
|
|
cookies[:visitor_id] = { value: visitor_id, expires: 24.months }
|
|
|
|
get :show, params: { id: 1 }
|
|
|
|
expect_redis_hll_tracking
|
|
expect_snowplow_tracking(nil)
|
|
end
|
|
end
|
|
|
|
context 'when user is not logged in and there is no visitor_id' do
|
|
it 'does not track the event' do
|
|
get :index
|
|
|
|
expect_no_tracking
|
|
end
|
|
|
|
it 'tracks the event when there is custom id' do
|
|
get :show, params: { id: 1 }
|
|
|
|
expect_redis_hll_tracking
|
|
expect_snowplow_tracking(nil)
|
|
end
|
|
|
|
context 'when there is no custom_id set' do
|
|
before do
|
|
allow(controller).to receive(:get_custom_id).and_return(nil)
|
|
|
|
get :show, params: { id: 2 }
|
|
end
|
|
|
|
it 'does not track the HLL event' do
|
|
expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
|
|
end
|
|
|
|
it 'tracks Snowplow event' do
|
|
expect_snowplow_tracking(nil)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|