debian-mirror-gitlab/spec/lib/gitlab/experimentation_spec.rb

381 lines
11 KiB
Ruby
Raw Normal View History

2019-12-21 20:55:43 +05:30
# frozen_string_literal: true
require 'spec_helper'
2020-07-28 23:09:34 +05:30
RSpec.describe Gitlab::Experimentation do
2019-12-26 22:10:19 +05:30
before do
stub_const('Gitlab::Experimentation::EXPERIMENTS', {
test_experiment: {
environment: environment,
tracking_category: 'Team'
}
})
2019-12-21 20:55:43 +05:30
2020-06-23 00:09:42 +05:30
Feature.enable_percentage_of_time(:test_experiment_experiment_percentage, enabled_percentage)
2019-12-21 20:55:43 +05:30
end
2019-12-26 22:10:19 +05:30
let(:environment) { Rails.env.test? }
2020-05-24 23:13:21 +05:30
let(:enabled_percentage) { 10 }
2019-12-26 22:10:19 +05:30
describe Gitlab::Experimentation::ControllerConcern, type: :controller do
controller(ApplicationController) do
include Gitlab::Experimentation::ControllerConcern
def index
head :ok
end
2019-12-21 20:55:43 +05:30
end
2019-12-26 22:10:19 +05:30
describe '#set_experimentation_subject_id_cookie' do
2020-04-08 14:13:33 +05:30
let(:do_not_track) { nil }
let(:cookie) { cookies.permanent.signed[:experimentation_subject_id] }
2019-12-21 20:55:43 +05:30
before do
2020-04-08 14:13:33 +05:30
request.headers['DNT'] = do_not_track if do_not_track.present?
2019-12-26 22:10:19 +05:30
get :index
2019-12-21 20:55:43 +05:30
end
2019-12-26 22:10:19 +05:30
context 'cookie is present' do
before do
cookies[:experimentation_subject_id] = 'test'
end
it 'does not change the cookie' do
expect(cookies[:experimentation_subject_id]).to eq 'test'
end
2019-12-21 20:55:43 +05:30
end
2019-12-26 22:10:19 +05:30
context 'cookie is not present' do
it 'sets a permanent signed cookie' do
2020-04-08 14:13:33 +05:30
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
2019-12-26 22:10:19 +05:30
end
2019-12-21 20:55:43 +05:30
end
end
2019-12-26 22:10:19 +05:30
describe '#experiment_enabled?' do
2020-04-08 14:13:33 +05:30
subject { controller.experiment_enabled?(:test_experiment) }
2019-12-26 22:10:19 +05:30
context 'cookie is not present' do
it 'calls Gitlab::Experimentation.enabled_for_user? with the name of the experiment and an experimentation_subject_index of nil' do
2020-03-13 15:44:24 +05:30
expect(Gitlab::Experimentation).to receive(:enabled_for_user?).with(:test_experiment, nil)
2019-12-26 22:10:19 +05:30
controller.experiment_enabled?(:test_experiment)
end
end
context 'cookie is present' do
before do
cookies.permanent.signed[:experimentation_subject_id] = 'abcd-1234'
get :index
end
it 'calls Gitlab::Experimentation.enabled_for_user? with the name of the experiment and an experimentation_subject_index of the modulo 100 of the hex value of the uuid' do
# 'abcd1234'.hex % 100 = 76
2020-03-13 15:44:24 +05:30
expect(Gitlab::Experimentation).to receive(:enabled_for_user?).with(:test_experiment, 76)
2019-12-26 22:10:19 +05:30
controller.experiment_enabled?(:test_experiment)
end
end
2020-04-08 14:13:33 +05:30
it 'returns true when DNT: 0 is set in the request' do
allow(Gitlab::Experimentation).to receive(:enabled_for_user?) { true }
controller.request.headers['DNT'] = '0'
is_expected.to be_truthy
end
it 'returns false when DNT: 1 is set in the request' do
allow(Gitlab::Experimentation).to receive(:enabled_for_user?) { true }
controller.request.headers['DNT'] = '1'
is_expected.to be_falsy
end
2019-12-26 22:10:19 +05:30
describe 'URL parameter to force enable experiment' do
2020-04-08 14:13:33 +05:30
it 'returns true unconditionally' do
2019-12-26 22:10:19 +05:30
get :index, params: { force_experiment: :test_experiment }
2020-04-08 14:13:33 +05:30
is_expected.to be_truthy
2019-12-26 22:10:19 +05:30
end
2019-12-21 20:55:43 +05:30
end
end
2019-12-26 22:10:19 +05:30
describe '#track_experiment_event' 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_user(test_experiment: true)
end
it 'tracks the event with the right parameters' do
expect(Gitlab::Tracking).to receive(:event).with(
'Team',
'start',
2020-03-13 15:44:24 +05:30
property: 'experimental_group',
value: 'team_id'
2019-12-26 22:10:19 +05:30
)
2020-03-13 15:44:24 +05:30
controller.track_experiment_event(:test_experiment, 'start', 'team_id')
2019-12-26 22:10:19 +05:30
end
end
context 'the user is part of the control group' do
before do
stub_experiment_for_user(test_experiment: false)
end
it 'tracks the event with the right parameters' do
expect(Gitlab::Tracking).to receive(:event).with(
'Team',
'start',
2020-03-13 15:44:24 +05:30
property: 'control_group',
value: 'team_id'
2019-12-26 22:10:19 +05:30
)
2020-03-13 15:44:24 +05:30
controller.track_experiment_event(:test_experiment, 'start', 'team_id')
2019-12-26 22:10:19 +05:30
end
end
2019-12-21 20:55:43 +05:30
end
2019-12-26 22:10:19 +05:30
context 'when the experiment is disabled' do
before do
stub_experiment(test_experiment: false)
end
it 'does not track the event' do
expect(Gitlab::Tracking).not_to receive(:event)
controller.track_experiment_event(:test_experiment, 'start')
end
2019-12-21 20:55:43 +05:30
end
end
2019-12-26 22:10:19 +05:30
describe '#frontend_experimentation_tracking_data' do
context 'when the experiment is enabled' do
before do
stub_experiment(test_experiment: true)
end
2019-12-21 20:55:43 +05:30
2019-12-26 22:10:19 +05:30
context 'the user is part of the experimental group' do
before do
stub_experiment_for_user(test_experiment: true)
end
it 'pushes the right parameters to gon' do
2020-03-13 15:44:24 +05:30
controller.frontend_experimentation_tracking_data(:test_experiment, 'start', 'team_id')
2019-12-26 22:10:19 +05:30
expect(Gon.tracking_data).to eq(
{
category: 'Team',
action: 'start',
2020-03-13 15:44:24 +05:30
property: 'experimental_group',
value: 'team_id'
2019-12-26 22:10:19 +05:30
}
)
end
end
2019-12-21 20:55:43 +05:30
2019-12-26 22:10:19 +05:30
context 'the user is part of the control group' do
before do
2020-01-01 13:55:28 +05:30
allow_next_instance_of(described_class) do |instance|
allow(instance).to receive(:experiment_enabled?).with(:test_experiment).and_return(false)
end
2019-12-26 22:10:19 +05:30
end
it 'pushes the right parameters to gon' do
2020-03-13 15:44:24 +05:30
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
2019-12-26 22:10:19 +05:30
controller.frontend_experimentation_tracking_data(:test_experiment, 'start')
expect(Gon.tracking_data).to eq(
{
category: 'Team',
action: 'start',
property: 'control_group'
}
)
end
end
end
2019-12-21 20:55:43 +05:30
2019-12-26 22:10:19 +05:30
context 'when the experiment is disabled' do
before do
stub_experiment(test_experiment: false)
end
2019-12-21 20:55:43 +05:30
2019-12-26 22:10:19 +05:30
it 'does not push data to gon' do
expect(Gon.method_defined?(:tracking_data)).to be_falsey
controller.track_experiment_event(:test_experiment, 'start')
end
end
end
2020-10-24 23:57:45 +05:30
describe '#record_experiment_user' 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_user(test_experiment: true)
end
it 'calls add_user on the Experiment model' do
expect(::Experiment).to receive(:add_user).with(:test_experiment, :experimental, user)
controller.record_experiment_user(:test_experiment)
end
end
context 'the user is part of the control group' do
before do
allow_next_instance_of(described_class) do |instance|
allow(instance).to receive(:experiment_enabled?).with(:test_experiment).and_return(false)
end
end
it 'calls add_user on the Experiment model' do
expect(::Experiment).to receive(:add_user).with(:test_experiment, :control, user)
controller.record_experiment_user(:test_experiment)
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)
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)
end
end
end
2020-11-24 15:15:51 +05:30
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').and_return('experimental_group')
expect(subject).to eq('Experiment::Category:experimental_group')
end
end
2019-12-26 22:10:19 +05:30
end
describe '.enabled?' do
subject { described_class.enabled?(:test_experiment) }
2019-12-21 20:55:43 +05:30
context 'feature toggle is enabled, we are on the right environment and we are selected' do
it { is_expected.to be_truthy }
end
describe 'experiment is not defined' do
it 'returns false' do
2019-12-26 22:10:19 +05:30
expect(described_class.enabled?(:missing_experiment)).to be_falsey
2019-12-21 20:55:43 +05:30
end
end
2020-05-24 23:13:21 +05:30
describe 'experiment is disabled' do
let(:enabled_percentage) { 0 }
2019-12-21 20:55:43 +05:30
2020-05-24 23:13:21 +05:30
it { is_expected.to be_falsey }
2019-12-21 20:55:43 +05:30
end
2020-05-24 23:13:21 +05:30
describe 'we are on the wrong environment' do
let(:environment) { ::Gitlab.com? }
2019-12-21 20:55:43 +05:30
2020-05-24 23:13:21 +05:30
it { is_expected.to be_falsey }
2019-12-21 20:55:43 +05:30
end
2019-12-26 22:10:19 +05:30
end
2019-12-21 20:55:43 +05:30
2019-12-26 22:10:19 +05:30
describe '.enabled_for_user?' do
subject { described_class.enabled_for_user?(:test_experiment, experimentation_subject_index) }
2019-12-21 20:55:43 +05:30
2019-12-26 22:10:19 +05:30
let(:experimentation_subject_index) { 9 }
context 'experiment is disabled' do
before do
allow(described_class).to receive(:enabled?).and_return(false)
2019-12-21 20:55:43 +05:30
end
2019-12-26 22:10:19 +05:30
it { is_expected.to be_falsey }
end
2019-12-21 20:55:43 +05:30
2019-12-26 22:10:19 +05:30
context 'experiment is enabled' do
before do
allow(described_class).to receive(:enabled?).and_return(true)
2019-12-21 20:55:43 +05:30
end
2019-12-26 22:10:19 +05:30
it { is_expected.to be_truthy }
describe 'experimentation_subject_index' do
context 'experimentation_subject_index is not set' do
let(:experimentation_subject_index) { nil }
2019-12-21 20:55:43 +05:30
2019-12-26 22:10:19 +05:30
it { is_expected.to be_falsey }
end
context 'experimentation_subject_index is an empty string' do
let(:experimentation_subject_index) { '' }
it { is_expected.to be_falsey }
end
context 'experimentation_subject_index outside enabled ratio' do
let(:experimentation_subject_index) { 11 }
it { is_expected.to be_falsey }
end
2019-12-21 20:55:43 +05:30
end
end
end
end