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/feature_spec.rb')
-rw-r--r--spec/lib/feature_spec.rb173
1 files changed, 172 insertions, 1 deletions
diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb
index 5dff9dbd995..1bcb2223012 100644
--- a/spec/lib/feature_spec.rb
+++ b/spec/lib/feature_spec.rb
@@ -249,10 +249,12 @@ RSpec.describe Feature, stub_feature_flags: false do
Feature::Definition.new('development/my_feature_flag.yml',
name: 'my_feature_flag',
type: 'development',
- default_enabled: false
+ default_enabled: default_enabled
).tap(&:validate!)
end
+ let(:default_enabled) { false }
+
before do
stub_env('LAZILY_CREATE_FEATURE_FLAG', '0')
@@ -275,6 +277,63 @@ RSpec.describe Feature, stub_feature_flags: false do
expect { described_class.enabled?(:my_feature_flag, default_enabled: true) }
.to raise_error(/The `default_enabled:` of/)
end
+
+ context 'when `default_enabled: :yaml` is used in code' do
+ it 'reads the default from the YAML definition' do
+ expect(described_class.enabled?(:my_feature_flag, default_enabled: :yaml)).to eq(false)
+ end
+
+ context 'when default_enabled is true in the YAML definition' do
+ let(:default_enabled) { true }
+
+ it 'reads the default from the YAML definition' do
+ expect(described_class.enabled?(:my_feature_flag, default_enabled: :yaml)).to eq(true)
+ end
+ end
+
+ context 'when YAML definition does not exist for an optional type' do
+ let(:optional_type) { described_class::Shared::TYPES.find { |name, attrs| attrs[:optional] }.first }
+
+ context 'when in dev or test environment' do
+ it 'raises an error for dev' do
+ expect { described_class.enabled?(:non_existent_flag, type: optional_type, default_enabled: :yaml) }
+ .to raise_error(
+ Feature::InvalidFeatureFlagError,
+ "The feature flag YAML definition for 'non_existent_flag' does not exist")
+ end
+ end
+
+ context 'when in production' do
+ before do
+ allow(Gitlab::ErrorTracking).to receive(:should_raise_for_dev?).and_return(false)
+ end
+
+ context 'when database exists' do
+ before do
+ allow(Gitlab::Database).to receive(:exists?).and_return(true)
+ end
+
+ it 'checks the persisted status and returns false' do
+ expect(described_class).to receive(:get).with(:non_existent_flag).and_call_original
+
+ expect(described_class.enabled?(:non_existent_flag, type: optional_type, default_enabled: :yaml)).to eq(false)
+ end
+ end
+
+ context 'when database does not exist' do
+ before do
+ allow(Gitlab::Database).to receive(:exists?).and_return(false)
+ end
+
+ it 'returns false without checking the status in the database' do
+ expect(described_class).not_to receive(:get)
+
+ expect(described_class.enabled?(:non_existent_flag, type: optional_type, default_enabled: :yaml)).to eq(false)
+ end
+ end
+ end
+ end
+ end
end
end
@@ -300,7 +359,119 @@ RSpec.describe Feature, stub_feature_flags: false do
end
end
+ shared_examples_for 'logging' do
+ let(:expected_action) { }
+ let(:expected_extra) { }
+
+ it 'logs the event' do
+ expect(Feature.logger).to receive(:info).with(key: key, action: expected_action, **expected_extra)
+
+ subject
+ end
+ end
+
+ describe '.enable' do
+ subject { described_class.enable(key, thing) }
+
+ let(:key) { :awesome_feature }
+ let(:thing) { true }
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :enable }
+ let(:expected_extra) { { "extra.thing" => "true" } }
+ end
+
+ context 'when thing is an actor' do
+ let(:thing) { create(:project) }
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :enable }
+ let(:expected_extra) { { "extra.thing" => "#{thing.flipper_id}" } }
+ end
+ end
+ end
+
+ describe '.disable' do
+ subject { described_class.disable(key, thing) }
+
+ let(:key) { :awesome_feature }
+ let(:thing) { false }
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :disable }
+ let(:expected_extra) { { "extra.thing" => "false" } }
+ end
+
+ context 'when thing is an actor' do
+ let(:thing) { create(:project) }
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :disable }
+ let(:expected_extra) { { "extra.thing" => "#{thing.flipper_id}" } }
+ end
+ end
+ end
+
+ describe '.enable_percentage_of_time' do
+ subject { described_class.enable_percentage_of_time(key, percentage) }
+
+ let(:key) { :awesome_feature }
+ let(:percentage) { 50 }
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :enable_percentage_of_time }
+ let(:expected_extra) { { "extra.percentage" => "#{percentage}" } }
+ end
+ end
+
+ describe '.disable_percentage_of_time' do
+ subject { described_class.disable_percentage_of_time(key) }
+
+ let(:key) { :awesome_feature }
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :disable_percentage_of_time }
+ let(:expected_extra) { {} }
+ end
+ end
+
+ describe '.enable_percentage_of_actors' do
+ subject { described_class.enable_percentage_of_actors(key, percentage) }
+
+ let(:key) { :awesome_feature }
+ let(:percentage) { 50 }
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :enable_percentage_of_actors }
+ let(:expected_extra) { { "extra.percentage" => "#{percentage}" } }
+ end
+ end
+
+ describe '.disable_percentage_of_actors' do
+ subject { described_class.disable_percentage_of_actors(key) }
+
+ let(:key) { :awesome_feature }
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :disable_percentage_of_actors }
+ let(:expected_extra) { {} }
+ end
+ end
+
describe '.remove' do
+ subject { described_class.remove(key) }
+
+ let(:key) { :awesome_feature }
+
+ before do
+ described_class.enable(key)
+ end
+
+ it_behaves_like 'logging' do
+ let(:expected_action) { :remove }
+ let(:expected_extra) { {} }
+ end
+
context 'for a non-persisted feature' do
it 'returns nil' do
expect(described_class.remove(:non_persisted_feature_flag)).to be_nil