Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/experimentation/controller_concern_spec.rb')
-rw-r--r--spec/lib/gitlab/experimentation/controller_concern_spec.rb675
1 files changed, 0 insertions, 675 deletions
diff --git a/spec/lib/gitlab/experimentation/controller_concern_spec.rb b/spec/lib/gitlab/experimentation/controller_concern_spec.rb
deleted file mode 100644
index 799884d7a74..00000000000
--- a/spec/lib/gitlab/experimentation/controller_concern_spec.rb
+++ /dev/null
@@ -1,675 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Experimentation::ControllerConcern, type: :controller do
- include TrackingHelpers
-
- before do
- stub_const('Gitlab::Experimentation::EXPERIMENTS', {
- test_experiment: {
- tracking_category: 'Team',
- rollout_strategy: rollout_strategy
- },
- my_experiment: {
- tracking_category: 'Team'
- }
- }
- )
-
- allow(Gitlab).to receive(:com?).and_return(is_gitlab_com)
-
- Feature.enable_percentage_of_time(:test_experiment_experiment_percentage, enabled_percentage)
- end
-
- let(:enabled_percentage) { 10 }
- let(:rollout_strategy) { nil }
- let(:is_gitlab_com) { true }
-
- controller(ApplicationController) do
- include Gitlab::Experimentation::ControllerConcern
-
- def index
- head :ok
- end
- end
-
- describe '#set_experimentation_subject_id_cookie' do
- let(:do_not_track) { nil }
- let(:cookie) { cookies.permanent.signed[:experimentation_subject_id] }
- let(:cookie_value) { nil }
-
- before do
- stub_do_not_track(do_not_track) if do_not_track.present?
- request.cookies[:experimentation_subject_id] = cookie_value if cookie_value
-
- get :index
- end
-
- context 'cookie is present' do
- let(:cookie_value) { 'test' }
-
- it 'does not change the cookie' do
- expect(cookies[:experimentation_subject_id]).to eq 'test'
- end
- end
-
- context 'cookie is not present' do
- it 'sets a permanent signed cookie' do
- expect(cookie).to be_present
- end
-
- context 'DNT: 0' do
- let(:do_not_track) { '0' }
-
- it 'sets a permanent signed cookie' do
- expect(cookie).to be_present
- end
- end
-
- context 'DNT: 1' do
- let(:do_not_track) { '1' }
-
- it 'does nothing' do
- expect(cookie).not_to be_present
- end
- end
- end
-
- context 'when not on gitlab.com' do
- let(:is_gitlab_com) { false }
-
- context 'when cookie was set' do
- let(:cookie_value) { 'test' }
-
- it 'cookie gets deleted' do
- expect(cookie).not_to be_present
- end
- end
-
- context 'when no cookie was set before' do
- it 'does nothing' do
- expect(cookie).not_to be_present
- end
- end
- end
- end
-
- describe '#push_frontend_experiment' do
- it 'pushes an experiment to the frontend' do
- gon = class_double('Gon')
- stub_experiment_for_subject(my_experiment: true)
- allow(controller).to receive(:gon).and_return(gon)
-
- expect(gon).to receive(:push).with({ experiments: { 'myExperiment' => true } }, true)
-
- controller.push_frontend_experiment(:my_experiment)
- end
- end
-
- describe '#experiment_enabled?' do
- def check_experiment(exp_key = :test_experiment, subject = nil)
- controller.experiment_enabled?(exp_key, subject: subject)
- end
-
- subject { check_experiment }
-
- context 'cookie is not present' do
- it { is_expected.to eq(false) }
- end
-
- context 'cookie is present' do
- before do
- cookies.permanent.signed[:experimentation_subject_id] = 'abcd-1234'
- get :index
- end
-
- it 'calls Gitlab::Experimentation.in_experiment_group? with the name of the experiment and the calculated experimentation_subject_index based on the uuid' do
- expect(Gitlab::Experimentation).to receive(:in_experiment_group?).with(:test_experiment, subject: 'abcd-1234')
-
- check_experiment(:test_experiment)
- end
-
- context 'when subject is given' do
- let(:rollout_strategy) { :user }
- let(:user) { build(:user) }
-
- it 'uses the subject' do
- expect(Gitlab::Experimentation).to receive(:in_experiment_group?).with(:test_experiment, subject: user)
-
- check_experiment(:test_experiment, user)
- end
- end
- end
-
- context 'do not track' do
- before do
- allow(Gitlab::Experimentation).to receive(:in_experiment_group?) { true }
- end
-
- context 'when do not track is disabled' do
- before do
- controller.request.headers['DNT'] = '0'
- end
-
- it { is_expected.to eq(true) }
- end
-
- context 'when do not track is enabled' do
- before do
- controller.request.headers['DNT'] = '1'
- end
-
- it { is_expected.to eq(false) }
- end
- end
-
- context 'URL parameter to force enable experiment' do
- it 'returns true unconditionally' do
- get :index, params: { force_experiment: :test_experiment }
-
- is_expected.to eq(true)
- end
- end
-
- context 'Cookie parameter to force enable experiment' do
- it 'returns true unconditionally' do
- cookies[:force_experiment] = 'test_experiment,another_experiment'
- get :index
-
- expect(check_experiment(:test_experiment)).to eq(true)
- expect(check_experiment(:another_experiment)).to eq(true)
- end
- end
- end
-
- describe '#track_experiment_event', :snowplow do
- let(:user) { build(:user) }
-
- context 'when the experiment is enabled' do
- before do
- stub_experiment(test_experiment: true)
- allow(controller).to receive(:current_user).and_return(user)
- end
-
- context 'the user is part of the experimental group' do
- before do
- stub_experiment_for_subject(test_experiment: true)
- end
-
- it 'tracks the event with the right parameters' do
- controller.track_experiment_event(:test_experiment, 'start', 1)
-
- expect_snowplow_event(
- category: 'Team',
- action: 'start',
- property: 'experimental_group',
- value: 1,
- user: user
- )
- end
- end
-
- context 'the user is part of the control group' do
- before do
- stub_experiment_for_subject(test_experiment: false)
- end
-
- it 'tracks the event with the right parameters' do
- controller.track_experiment_event(:test_experiment, 'start', 1)
-
- expect_snowplow_event(
- category: 'Team',
- action: 'start',
- property: 'control_group',
- value: 1,
- user: user
- )
- end
- end
-
- context 'do not track is disabled' do
- before do
- stub_do_not_track('0')
- end
-
- it 'does track the event' do
- controller.track_experiment_event(:test_experiment, 'start', 1)
-
- expect_snowplow_event(
- category: 'Team',
- action: 'start',
- property: 'control_group',
- value: 1,
- user: user
- )
- end
- end
-
- context 'do not track enabled' do
- before do
- stub_do_not_track('1')
- end
-
- it 'does not track the event' do
- controller.track_experiment_event(:test_experiment, 'start', 1)
-
- expect_no_snowplow_event
- end
- end
-
- context 'subject is provided' do
- before do
- stub_experiment_for_subject(test_experiment: false)
- end
-
- it "provides the subject's hashed global_id as label" do
- experiment_subject = double(:subject, to_global_id: 'abc')
- allow(Gitlab::Experimentation).to receive(:valid_subject_for_rollout_strategy?).and_return(true)
-
- controller.track_experiment_event(:test_experiment, 'start', 1, subject: experiment_subject)
-
- expect_snowplow_event(
- category: 'Team',
- action: 'start',
- property: 'control_group',
- value: 1,
- label: Digest::SHA256.hexdigest('abc'),
- user: user
- )
- end
-
- it "provides the subject's hashed string representation as label" do
- experiment_subject = 'somestring'
-
- controller.track_experiment_event(:test_experiment, 'start', 1, subject: experiment_subject)
-
- expect_snowplow_event(
- category: 'Team',
- action: 'start',
- property: 'control_group',
- value: 1,
- label: Digest::SHA256.hexdigest('somestring'),
- user: user
- )
- end
- end
-
- context 'no subject is provided but cookie is set' do
- before do
- get :index
- stub_experiment_for_subject(test_experiment: false)
- end
-
- it 'uses the experimentation_subject_id as fallback' do
- controller.track_experiment_event(:test_experiment, 'start', 1)
-
- expect_snowplow_event(
- category: 'Team',
- action: 'start',
- property: 'control_group',
- value: 1,
- label: cookies.permanent.signed[:experimentation_subject_id],
- user: user
- )
- end
- end
- end
-
- context 'when the experiment is disabled' do
- before do
- stub_experiment(test_experiment: false)
- end
-
- it 'does not track the event' do
- controller.track_experiment_event(:test_experiment, 'start')
-
- expect_no_snowplow_event
- end
- end
- end
-
- describe '#frontend_experimentation_tracking_data' do
- context 'when the experiment is enabled' do
- before do
- stub_experiment(test_experiment: true)
- end
-
- context 'the user is part of the experimental group' do
- before do
- stub_experiment_for_subject(test_experiment: true)
- end
-
- it 'pushes the right parameters to gon' do
- controller.frontend_experimentation_tracking_data(:test_experiment, 'start', 'team_id')
- expect(Gon.tracking_data).to eq(
- {
- category: 'Team',
- action: 'start',
- property: 'experimental_group',
- value: 'team_id'
- }
- )
- end
- end
-
- context 'the user is part of the control group' do
- before do
- stub_experiment_for_subject(test_experiment: false)
- end
-
- it 'pushes the right parameters to gon' do
- controller.frontend_experimentation_tracking_data(:test_experiment, 'start', 'team_id')
- expect(Gon.tracking_data).to eq(
- {
- category: 'Team',
- action: 'start',
- property: 'control_group',
- value: 'team_id'
- }
- )
- end
-
- it 'does not send nil value to gon' do
- controller.frontend_experimentation_tracking_data(:test_experiment, 'start')
- expect(Gon.tracking_data).to eq(
- {
- category: 'Team',
- action: 'start',
- property: 'control_group'
- }
- )
- end
- end
-
- context 'do not track disabled' do
- before do
- stub_do_not_track('0')
- end
-
- it 'pushes the right parameters to gon' do
- controller.frontend_experimentation_tracking_data(:test_experiment, 'start')
-
- expect(Gon.tracking_data).to eq(
- {
- category: 'Team',
- action: 'start',
- property: 'control_group'
- }
- )
- end
- end
-
- context 'do not track enabled' do
- before do
- stub_do_not_track('1')
- end
-
- it 'does not push data to gon' do
- controller.frontend_experimentation_tracking_data(:test_experiment, 'start')
-
- expect(Gon.method_defined?(:tracking_data)).to eq(false)
- end
- end
- end
-
- context 'when the experiment is disabled' do
- before do
- stub_experiment(test_experiment: false)
- end
-
- it 'does not push data to gon' do
- expect(Gon.method_defined?(:tracking_data)).to eq(false)
- controller.track_experiment_event(:test_experiment, 'start')
- end
- end
- end
-
- describe '#record_experiment_user' do
- let(:user) { build(:user) }
- let(:context) { { a: 42 } }
-
- context 'when the experiment is enabled' do
- before do
- stub_experiment(test_experiment: true)
- allow(controller).to receive(:current_user).and_return(user)
- end
-
- context 'the user is part of the experimental group' do
- before do
- stub_experiment_for_subject(test_experiment: true)
- end
-
- it 'calls add_user on the Experiment model' do
- expect(::Experiment).to receive(:add_user).with(:test_experiment, :experimental, user, context)
-
- controller.record_experiment_user(:test_experiment, context)
- end
-
- context 'with a cookie based rollout strategy' do
- it 'calls tracking_group with a nil subject' do
- expect(controller).to receive(:tracking_group).with(:test_experiment, nil, subject: nil).and_return(:experimental)
- allow(::Experiment).to receive(:add_user).with(:test_experiment, :experimental, user, context)
-
- controller.record_experiment_user(:test_experiment, context)
- end
- end
-
- context 'with a user based rollout strategy' do
- let(:rollout_strategy) { :user }
-
- it 'calls tracking_group with a user subject' do
- expect(controller).to receive(:tracking_group).with(:test_experiment, nil, subject: user).and_return(:experimental)
- allow(::Experiment).to receive(:add_user).with(:test_experiment, :experimental, user, context)
-
- controller.record_experiment_user(:test_experiment, context)
- end
- end
- end
-
- context 'the user is part of the control group' do
- before do
- stub_experiment_for_subject(test_experiment: false)
- end
-
- it 'calls add_user on the Experiment model' do
- expect(::Experiment).to receive(:add_user).with(:test_experiment, :control, user, context)
-
- controller.record_experiment_user(:test_experiment, context)
- end
- end
- end
-
- context 'when the experiment is disabled' do
- before do
- stub_experiment(test_experiment: false)
- allow(controller).to receive(:current_user).and_return(user)
- end
-
- it 'does not call add_user on the Experiment model' do
- expect(::Experiment).not_to receive(:add_user)
-
- controller.record_experiment_user(:test_experiment, context)
- end
- end
-
- context 'when there is no current_user' do
- before do
- stub_experiment(test_experiment: true)
- end
-
- it 'does not call add_user on the Experiment model' do
- expect(::Experiment).not_to receive(:add_user)
-
- controller.record_experiment_user(:test_experiment, context)
- end
- end
-
- context 'do not track' do
- before do
- stub_experiment(test_experiment: true)
- allow(controller).to receive(:current_user).and_return(user)
- end
-
- context 'is disabled' do
- before do
- stub_do_not_track('0')
- stub_experiment_for_subject(test_experiment: false)
- end
-
- it 'calls add_user on the Experiment model' do
- expect(::Experiment).to receive(:add_user).with(:test_experiment, :control, user, context)
-
- controller.record_experiment_user(:test_experiment, context)
- end
- end
-
- context 'is enabled' do
- before do
- stub_do_not_track('1')
- end
-
- it 'does not call add_user on the Experiment model' do
- expect(::Experiment).not_to receive(:add_user)
-
- controller.record_experiment_user(:test_experiment, context)
- end
- end
- end
- end
-
- describe '#record_experiment_group' do
- let(:group) { 'a group object' }
- let(:experiment_key) { :some_experiment_key }
- let(:dnt_enabled) { false }
- let(:experiment_active) { true }
- let(:rollout_strategy) { :whatever }
- let(:variant) { 'variant' }
-
- before do
- allow(controller).to receive(:dnt_enabled?).and_return(dnt_enabled)
- allow(::Gitlab::Experimentation).to receive(:active?).and_return(experiment_active)
- allow(::Gitlab::Experimentation).to receive(:rollout_strategy).and_return(rollout_strategy)
- allow(controller).to receive(:tracking_group).and_return(variant)
- allow(::Experiment).to receive(:add_group)
- end
-
- subject(:record_experiment_group) { controller.record_experiment_group(experiment_key, group) }
-
- shared_examples 'exits early without recording' do
- it 'returns early without recording the group as an ExperimentSubject' do
- expect(::Experiment).not_to receive(:add_group)
- record_experiment_group
- end
- end
-
- shared_examples 'calls tracking_group' do |using_cookie_rollout|
- it "calls tracking_group with #{using_cookie_rollout ? 'a nil' : 'the group as the'} subject" do
- expect(controller).to receive(:tracking_group).with(experiment_key, nil, subject: using_cookie_rollout ? nil : group).and_return(variant)
- record_experiment_group
- end
- end
-
- shared_examples 'records the group' do
- it 'records the group' do
- expect(::Experiment).to receive(:add_group).with(experiment_key, group: group, variant: variant)
- record_experiment_group
- end
- end
-
- context 'when DNT is enabled' do
- let(:dnt_enabled) { true }
-
- include_examples 'exits early without recording'
- end
-
- context 'when the experiment is not active' do
- let(:experiment_active) { false }
-
- include_examples 'exits early without recording'
- end
-
- context 'when a nil group is given' do
- let(:group) { nil }
-
- include_examples 'exits early without recording'
- end
-
- context 'when the experiment uses a cookie-based rollout strategy' do
- let(:rollout_strategy) { :cookie }
-
- include_examples 'calls tracking_group', true
- include_examples 'records the group'
- end
-
- context 'when the experiment uses a non-cookie-based rollout strategy' do
- let(:rollout_strategy) { :group }
-
- include_examples 'calls tracking_group', false
- include_examples 'records the group'
- end
- end
-
- describe '#record_experiment_conversion_event' do
- let(:user) { build(:user) }
-
- before do
- allow(controller).to receive(:dnt_enabled?).and_return(false)
- allow(controller).to receive(:current_user).and_return(user)
- stub_experiment(test_experiment: true)
- end
-
- subject(:record_conversion_event) do
- controller.record_experiment_conversion_event(:test_experiment)
- end
-
- it 'records the conversion event for the experiment & user' do
- expect(::Experiment).to receive(:record_conversion_event).with(:test_experiment, user, {})
- record_conversion_event
- end
-
- shared_examples 'does not record the conversion event' do
- it 'does not record the conversion event' do
- expect(::Experiment).not_to receive(:record_conversion_event)
- record_conversion_event
- end
- end
-
- context 'when DNT is enabled' do
- before do
- allow(controller).to receive(:dnt_enabled?).and_return(true)
- end
-
- include_examples 'does not record the conversion event'
- end
-
- context 'when there is no current user' do
- before do
- allow(controller).to receive(:current_user).and_return(nil)
- end
-
- include_examples 'does not record the conversion event'
- end
-
- context 'when the experiment is not enabled' do
- before do
- stub_experiment(test_experiment: false)
- end
-
- include_examples 'does not record the conversion event'
- end
- end
-
- describe '#experiment_tracking_category_and_group' do
- let_it_be(:experiment_key) { :test_something }
-
- subject { controller.experiment_tracking_category_and_group(experiment_key) }
-
- it 'returns a string with the experiment tracking category & group joined with a ":"' do
- expect(controller).to receive(:tracking_category).with(experiment_key).and_return('Experiment::Category')
- expect(controller).to receive(:tracking_group).with(experiment_key, '_group', subject: nil).and_return('experimental_group')
-
- expect(subject).to eq('Experiment::Category:experimental_group')
- end
- end
-end