gitlab-ce/spec/controllers/concerns/product_analytics_tracking_...

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