diff options
author | Robert Speicher <rspeicher@gmail.com> | 2018-09-11 16:40:42 -0500 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2018-09-13 11:52:54 -0500 |
commit | 6b46db0d8a53691f1c680d435c8e9572e1e16041 (patch) | |
tree | 7e27718f45e4157cf38ae1ffd010b0da7ca8783a | |
parent | 733cae702222771a734db5b3b5ab8fe3e2eb7538 (diff) | |
download | gitlab-ce-6b46db0d8a53691f1c680d435c8e9572e1e16041.tar.gz |
Add `Feature.enabled_and_licensed?` helper method
When no license is available (such as in CE), this is equivalent to
calling `enabled?`.
When a license is available but the specified feature isn't
license-gated, this is also equivalent to calling `enabled?`.
When a license is available and the specified feature is license-gated,
this method will check both that the feature is enabled, and that it's
available to the license.
-rw-r--r-- | lib/feature.rb | 26 | ||||
-rw-r--r-- | spec/lib/feature_spec.rb | 50 |
2 files changed, 76 insertions, 0 deletions
diff --git a/lib/feature.rb b/lib/feature.rb index f4b57376313..db05fd01f0f 100644 --- a/lib/feature.rb +++ b/lib/feature.rb @@ -54,6 +54,32 @@ class Feature !default_enabled || Feature.persisted?(feature) ? feature.enabled?(thing) : true end + # Check if a feature is both enabled and licensed + # + # When no license is available (such as in CE), this is equivalent to + # calling `enabled?`. + # + # When a license is available but the specified feature isn't license-gated, + # this is also equivalent to calling `enabled?`. + # + # When a license is available and the specified feature is license-gated, + # this method will check both that the feature is enabled, and that it's + # available to the license. + def enabled_and_licensed?(key, thing = nil, default_enabled: false) + return false unless enabled?(key, thing, default_enabled: default_enabled) + return true unless defined?(License) + + license = License.current + + if license.features.include?(key) + license.feature_available?(key) + else + # Not all feature flags are gated by License. If the license doesn't + # define this key as a feature, we'll consider it good. + true + end + end + def disabled?(key, thing = nil, default_enabled: false) # we need to make different method calls to make it easy to mock / define expectations in test mode thing.nil? ? !enabled?(key, default_enabled: default_enabled) : !enabled?(key, thing, default_enabled: default_enabled) diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb index 48c0ba8a653..6c29c1b1e2c 100644 --- a/spec/lib/feature_spec.rb +++ b/spec/lib/feature_spec.rb @@ -159,6 +159,56 @@ describe Feature do end end + describe '.enabled_and_licensed?' do + it 'passes all arguments to `enabled?`' do + expect(described_class).to receive(:enabled?) + .with(:foo, 'thing', default_enabled: true) + .and_return(false) + + expect(described_class.enabled_and_licensed?(:foo, 'thing', default_enabled: true)) + .to eq false + end + + context 'with an enabled feature' do + before do + allow(described_class).to receive(:enabled?).and_return(true) + end + + # Behavior changes slightly when we're in EE and License is available + if defined?(License) + context 'with an unregistered license feature' do + it 'returns true' do + expect(described_class.enabled_and_licensed?(:not_a_real_feature)) + .to eq true + end + end + + context 'with a registered license feature' do + it 'delegates to `License.feature_available?`' do + license = License.current + + expect(license.features).to receive(:include?) + .with(:a_very_real_feature) + .and_return(true) + expect(license).to receive(:feature_available?) + .with(:a_very_real_feature) + .and_return(true) + expect(License).to receive(:current).and_return(license) + + expect(described_class.enabled_and_licensed?(:a_very_real_feature)) + .to eq true + end + end + else + context 'with no License definition' do + it 'returns true' do + expect(described_class.enabled_and_licensed?(:foo)).to eq true + end + end + end + end + end + describe '.disable?' do it 'returns true for undefined feature' do expect(described_class.disabled?(:some_random_feature_flag)).to be_truthy |