Commit 304bdcec authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch 'reminder-emails-experimentation' into 'master'

Add Experimentation.enabled_for_attribute? method

See merge request gitlab-org/gitlab!42847
parents 011c0c12 531ccaa5
...@@ -62,6 +62,9 @@ module Gitlab ...@@ -62,6 +62,9 @@ module Gitlab
}, },
invite_email: { invite_email: {
tracking_category: 'Growth::Acquisition::Experiment::InviteEmail' tracking_category: 'Growth::Acquisition::Experiment::InviteEmail'
},
invitation_reminders: {
tracking_category: 'Growth::Acquisition::Experiment::InvitationReminders'
} }
}.freeze }.freeze
...@@ -94,7 +97,7 @@ module Gitlab ...@@ -94,7 +97,7 @@ module Gitlab
def experiment_enabled?(experiment_key) def experiment_enabled?(experiment_key)
return false if dnt_enabled? return false if dnt_enabled?
return true if Experimentation.enabled_for_user?(experiment_key, experimentation_subject_index) return true if Experimentation.enabled_for_value?(experiment_key, experimentation_subject_index)
return true if forced_enabled?(experiment_key) return true if forced_enabled?(experiment_key)
false false
...@@ -183,9 +186,14 @@ module Gitlab ...@@ -183,9 +186,14 @@ module Gitlab
experiment.enabled? && experiment.enabled_for_environment? experiment.enabled? && experiment.enabled_for_environment?
end end
def enabled_for_user?(experiment_key, experimentation_subject_index) def enabled_for_attribute?(experiment_key, attribute)
index = Digest::SHA1.hexdigest(attribute).hex % 100
enabled_for_value?(experiment_key, index)
end
def enabled_for_value?(experiment_key, experimentation_subject_index)
enabled?(experiment_key) && enabled?(experiment_key) &&
experiment(experiment_key).enabled_for_experimentation_subject?(experimentation_subject_index) experiment(experiment_key).enabled_for_index?(experimentation_subject_index)
end end
end end
...@@ -200,10 +208,10 @@ module Gitlab ...@@ -200,10 +208,10 @@ module Gitlab
environment environment
end end
def enabled_for_experimentation_subject?(experimentation_subject_index) def enabled_for_index?(index)
return false if experimentation_subject_index.blank? return false if index.blank?
experimentation_subject_index <= experiment_percentage index <= experiment_percentage
end end
private private
......
...@@ -73,8 +73,8 @@ RSpec.describe Gitlab::Experimentation do ...@@ -73,8 +73,8 @@ RSpec.describe Gitlab::Experimentation do
subject { controller.experiment_enabled?(:test_experiment) } subject { controller.experiment_enabled?(:test_experiment) }
context 'cookie is not present' do 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 it 'calls Gitlab::Experimentation.enabled_for_value? with the name of the experiment and an experimentation_subject_index of nil' do
expect(Gitlab::Experimentation).to receive(:enabled_for_user?).with(:test_experiment, nil) expect(Gitlab::Experimentation).to receive(:enabled_for_value?).with(:test_experiment, nil)
controller.experiment_enabled?(:test_experiment) controller.experiment_enabled?(:test_experiment)
end end
end end
...@@ -85,22 +85,22 @@ RSpec.describe Gitlab::Experimentation do ...@@ -85,22 +85,22 @@ RSpec.describe Gitlab::Experimentation do
get :index get :index
end 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 it 'calls Gitlab::Experimentation.enabled_for_value? 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 # 'abcd1234'.hex % 100 = 76
expect(Gitlab::Experimentation).to receive(:enabled_for_user?).with(:test_experiment, 76) expect(Gitlab::Experimentation).to receive(:enabled_for_value?).with(:test_experiment, 76)
controller.experiment_enabled?(:test_experiment) controller.experiment_enabled?(:test_experiment)
end end
end end
it 'returns true when DNT: 0 is set in the request' do it 'returns true when DNT: 0 is set in the request' do
allow(Gitlab::Experimentation).to receive(:enabled_for_user?) { true } allow(Gitlab::Experimentation).to receive(:enabled_for_value?) { true }
controller.request.headers['DNT'] = '0' controller.request.headers['DNT'] = '0'
is_expected.to be_truthy is_expected.to be_truthy
end end
it 'returns false when DNT: 1 is set in the request' do it 'returns false when DNT: 1 is set in the request' do
allow(Gitlab::Experimentation).to receive(:enabled_for_user?) { true } allow(Gitlab::Experimentation).to receive(:enabled_for_value?) { true }
controller.request.headers['DNT'] = '1' controller.request.headers['DNT'] = '1'
is_expected.to be_falsy is_expected.to be_falsy
...@@ -336,8 +336,8 @@ RSpec.describe Gitlab::Experimentation do ...@@ -336,8 +336,8 @@ RSpec.describe Gitlab::Experimentation do
end end
end end
describe '.enabled_for_user?' do describe '.enabled_for_value?' do
subject { described_class.enabled_for_user?(:test_experiment, experimentation_subject_index) } subject { described_class.enabled_for_value?(:test_experiment, experimentation_subject_index) }
let(:experimentation_subject_index) { 9 } let(:experimentation_subject_index) { 9 }
...@@ -377,4 +377,32 @@ RSpec.describe Gitlab::Experimentation do ...@@ -377,4 +377,32 @@ RSpec.describe Gitlab::Experimentation do
end end
end end
end end
describe '.enabled_for_attribute?' do
subject { described_class.enabled_for_attribute?(:test_experiment, attribute) }
let(:attribute) { 'abcd' } # Digest::SHA1.hexdigest('abcd').hex % 100 = 7
context 'experiment is disabled' do
before do
allow(described_class).to receive(:enabled?).and_return(false)
end
it { is_expected.to be false }
end
context 'experiment is enabled' do
before do
allow(described_class).to receive(:enabled?).and_return(true)
end
it { is_expected.to be true }
context 'outside enabled ratio' do
let(:attribute) { 'abc' } # Digest::SHA1.hexdigest('abc').hex % 100 = 17
it { is_expected.to be false }
end
end
end
end end
...@@ -22,10 +22,10 @@ module StubExperiments ...@@ -22,10 +22,10 @@ module StubExperiments
# Examples # Examples
# - `stub_experiment_for_user(signup_flow: false)` ... Disable `signup_flow` experiment for user. # - `stub_experiment_for_user(signup_flow: false)` ... Disable `signup_flow` experiment for user.
def stub_experiment_for_user(experiments) def stub_experiment_for_user(experiments)
allow(Gitlab::Experimentation).to receive(:enabled_for_user?).and_call_original allow(Gitlab::Experimentation).to receive(:enabled_for_value?).and_call_original
experiments.each do |experiment_key, enabled| experiments.each do |experiment_key, enabled|
allow(Gitlab::Experimentation).to receive(:enabled_for_user?).with(experiment_key, anything) { enabled } allow(Gitlab::Experimentation).to receive(:enabled_for_value?).with(experiment_key, anything) { enabled }
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment